Merge "MsoUtil refactor"
[vid.git] / vid-app-common / src / main / webapp / app / vid / scripts / directives / parameterBlockDirective.js
1 /*-\r
2  * ============LICENSE_START=======================================================\r
3  * VID\r
4  * ================================================================================\r
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.\r
6  * Modifications Copyright (C) 2019 IBM.\r
7  * ================================================================================\r
8  * Licensed under the Apache License, Version 2.0 (the "License");\r
9  * you may not use this file except in compliance with the License.\r
10  * You may obtain a copy of the License at\r
11  * \r
12  *      http://www.apache.org/licenses/LICENSE-2.0\r
13  * \r
14  * Unless required by applicable law or agreed to in writing, software\r
15  * distributed under the License is distributed on an "AS IS" BASIS,\r
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
17  * See the License for the specific language governing permissions and\r
18  * limitations under the License.\r
19  * ============LICENSE_END=========================================================\r
20  */\r
21 \r
22 "use strict";\r
23 \r
24 var parameterBlockDirective = function($log, PARAMETER, UtilityService, $compile) {\r
25     /*\r
26      * If "IS_SINGLE_OPTION_AUTO_SELECTED" is set to "true" ...\r
27      * \r
28      * IF these 3 conditions all exist:\r
29      * \r
30      * 1) The parameter type is PARAMETER.SELECT\r
31      * \r
32      * 2) AND the "prompt" attribute is set to a string.\r
33      *\r
34      * 3) AND the optionList" only contains a single entry\r
35      * \r
36      * THEN the "prompt" will not be displayed as an initial select option.\r
37      */\r
38 \r
39     var IS_SINGLE_OPTION_AUTO_SELECTED = true;\r
40 \r
41     /*\r
42      * Optionally remove "nameStyle" and "valueStyle" "width" entries to set\r
43      * dynamic sizing.\r
44      */\r
45     var tableStyle = "width: auto; margin: 0 auto; border-collapse: collapse; border: none;";\r
46     var nameStyle = "width: 220px; text-align: left; vertical-align: middle; font-weight: bold; padding: 3px 5px; border: none;";\r
47     var valueStyle = "width: 400px; text-align: left; vertical-align: middle; padding: 3px 5px; border: none;";\r
48     var checkboxValueStyle = "width: 400px; text-align: center; vertical-align: middle; padding: 3px 5px; border: none;"\r
49     var textInputStyle = "height: 25px; padding: 2px 5px;";\r
50     var checkboxInputStyle = "height: 18px; width: 18px; padding: 2px 5px;";\r
51     var selectStyle = "height: 25px; padding: 2px; text-align: center;";\r
52     var requiredLabelStyle = "width: 25px; padding: 5px 10px 10px 5px;";\r
53 \r
54 \r
55     var getParameterHtml = function(parameter, editable) {\r
56         var style = valueStyle;\r
57         var attributeString = "";\r
58         if (parameter.type === PARAMETER.BOOLEAN) {\r
59             style = checkboxValueStyle;\r
60         }\r
61         if (UtilityService.hasContents(parameter.description)) {\r
62             attributeString += " title=' " + parameter.description + " '";\r
63         }\r
64         var rowstyle='';\r
65         if(parameter.type == 'file' && !parameter.isVisiblity){\r
66             rowstyle = ' style="display:none;"';\r
67         }\r
68         var html = "<tr"+rowstyle+"><td style='" + nameStyle + "'" + attributeString + ">"\r
69             + getNameHtml(parameter) + "</td>";\r
70         if (editable === undefined) {\r
71             if (UtilityService.hasContents(parameter.value)) {\r
72                 html += "<td data-tests-id='" +  getParameterName(parameter) + "' style='" + style + "'>" + parameter.value;\r
73             } else {\r
74                 html += "<td data-tests-id='" +  getParameterName(parameter) + "' style='" + style + "'>";\r
75             }\r
76         } else {\r
77             html += "<td style='" + style + "'>" + getValueHtml(parameter);\r
78         }\r
79         html += "</td></tr>";\r
80         return html;\r
81     };\r
82 \r
83     var updateParameter = function(parameter, element, editable) {\r
84         $(element).parent().parent().children("td").first().html(\r
85             getNameHtml(parameter));\r
86         if (editable === undefined) {\r
87             $(element).html(parameter.value);\r
88         } else {\r
89             $(element).parent().html(getValueHtml(parameter));\r
90         }\r
91     };\r
92 \r
93     var getNameHtml = function(parameter) {\r
94         if (parameter.isVisible === false) {\r
95             return "";\r
96         }\r
97         var name = getParameterName(parameter);\r
98 \r
99         var requiredLabel = "";\r
100         if (parameter.isRequired) {\r
101             requiredLabel = "<img src='app/vid/images/asterisk.png' style='"\r
102                 + requiredLabelStyle + "'></img>";\r
103         }\r
104         return name + ":" + requiredLabel;\r
105     };\r
106 \r
107     var getParameterName = function(parameter) {\r
108         var name = "";\r
109         if (UtilityService.hasContents(parameter.name)) {\r
110             name = parameter.name;\r
111         } else {\r
112             name = parameter.id;\r
113         }\r
114         return name;\r
115     }\r
116 \r
117     var getValueHtml = function(parameter) {\r
118 \r
119         var textInputPrompt = "Enter data";\r
120         var attributeString = " data-tests-id='" + parameter.id +"' parameter-id='" + parameter.id + "'";\r
121         var additionalStyle = "";\r
122         if (parameter.isEnabled === false) {\r
123             attributeString += " disabled='disabled'";\r
124         }\r
125         if (parameter.isRequired) {\r
126             attributeString += " is-required='true'";\r
127         }\r
128         if (UtilityService.hasContents(parameter.description)) {\r
129             attributeString += " title=' " + parameter.description + " '";\r
130         }\r
131         if (UtilityService.hasContents(parameter.isReadOnly) && (parameter.isReadOnly === true)) {\r
132             attributeString += " readonly";\r
133         }\r
134         if ( (UtilityService.hasContents(parameter.maxLength)) && (UtilityService.hasContents(parameter.minLength)) ) {\r
135             attributeString += " pattern='.{" + parameter.minLength + "," + parameter.maxLength + "}' required";\r
136         }\r
137         else if (UtilityService.hasContents(parameter.maxLength)) {\r
138             attributeString += " maxlength='" + parameter.maxLength + "'";\r
139         }\r
140         else if (UtilityService.hasContents(parameter.minLength)) {\r
141             attributeString += " pattern='.{" + parameter.minLength + ",}'"\r
142         }\r
143         if (parameter.isVisible === false) {\r
144             additionalStyle = " visibility: hidden;";\r
145         }\r
146 \r
147         var name = "";\r
148         if (UtilityService.hasContents(parameter.name)) {\r
149             name = parameter.name;\r
150         } else {\r
151             name = parameter.id;\r
152         }\r
153         attributeString += " parameter-name='" + name + "'";\r
154 \r
155         if ( parameter.type === PARAMETER.MAP ) {\r
156             textInputPrompt = "{<key1>: <value1>,\.\.\.,<keyN>: <valueN>}";\r
157         }\r
158 \r
159         if ( parameter.type === PARAMETER.LIST ) {\r
160             textInputPrompt = "[<value1>,\.\.\.,<valueN>]";\r
161         }\r
162 \r
163         switch (parameter.type) {\r
164             case PARAMETER.BOOLEAN:\r
165                 if (parameter.value) {\r
166                     return "<select" + attributeString + " style='" + selectStyle\r
167                         + additionalStyle + "'>" + "<option value=true>true</option>"\r
168                         + "<option value=false>false</option>"\r
169                     + "</select>";\r
170                 }else{\r
171                     return "<select" + attributeString + " style='" + selectStyle\r
172                         + additionalStyle + "'>" + "<option value=false>false</option>"\r
173                         + "<option value=true>true</option>"\r
174                         + "</select>";\r
175                 }\r
176                 break;\r
177             case PARAMETER.CHECKBOX:\r
178                 if (parameter.value) {\r
179                     return "<input type='checkbox' "+attributeString+ " checked='checked' style='"+checkboxInputStyle+"'"\r
180                         + " value='true'/>";\r
181                 }else{\r
182                     return "<input type='checkbox' "+attributeString+ "' style='"+checkboxInputStyle+"'"\r
183                         + " value='false'/>";\r
184                 }\r
185                 break;\r
186             case PARAMETER.FILE:\r
187                 return "<input type='file' "+attributeString+ " id='"+parameter.id+"' value='"+parameter.value+"'/>";\r
188                 break;\r
189             case PARAMETER.NUMBER:\r
190                 var value=parameter.value;\r
191                 var parameterSpec = "<input type='number'" + attributeString + " style='" + textInputStyle + additionalStyle + "'";\r
192 \r
193                 if ( UtilityService.hasContents(parameter.min) ) {\r
194                     parameterSpec += " min='" + parameter.min + "'";\r
195                 }\r
196                 if ( UtilityService.hasContents(parameter.max) ) {\r
197                     parameterSpec += " max='" + parameter.max + "'";\r
198                 }\r
199                 if (UtilityService.hasContents(value)) {\r
200                     parameterSpec += " value='" + value + "'";\r
201                 }\r
202                 parameterSpec += ">";\r
203 \r
204                 /*if(!isNaN(value) && value.toString().index('.') != -1){\r
205                  //float\r
206                  return "<input type='text'" + attributeString + " style='"\r
207                  + textInputStyle + additionalStyle + "' only-integers" + value\r
208                  + "></input>";\r
209                  } else {\r
210                  //integer\r
211                  return "<input type='text'" + attributeString + " style='"\r
212                  + textInputStyle + additionalStyle + "'  only-float" + value\r
213                  + "></input>";\r
214                  }*/\r
215                 return (parameterSpec);\r
216                 break;\r
217             case PARAMETER.SELECT:\r
218                 if (UtilityService.hasContents(parameter.prompt)) {\r
219                     attributeString += " prompt='" + parameter.prompt + "'";\r
220                 }\r
221                 return "<select" + attributeString + " style='" + selectStyle\r
222                     + additionalStyle + "'>" + getOptionListHtml(parameter)\r
223                     + "</select>";\r
224                 break;\r
225             case PARAMETER.MULTI_SELECT:\r
226                 return '<multiselect id="' + parameter.id + '"' + attributeString + ' ng-model="multiselectModel.' + parameter.id + '" options="getOptionsList(\'' + parameter.id + '\')" display-prop="name" id-prop="id"></multiselect>';\r
227                 break;\r
228             case PARAMETER.STRING:\r
229             default:\r
230                 var value = "";\r
231                 if (UtilityService.hasContents(parameter.value)) {\r
232                     value = " value='" + parameter.value + "'";\r
233                 }\r
234                 if (UtilityService.hasContents(parameter.prompt)) {\r
235                     attributeString += " placeholder='" + parameter.prompt + "'";\r
236                 } else if (textInputPrompt !== "") {\r
237                     attributeString += " placeholder='" + textInputPrompt + "'";\r
238                 }\r
239                 var finalString = "<input type='text'" + attributeString + " style='"\r
240                     + textInputStyle + additionalStyle + "'" + value\r
241                     + ">";\r
242                 return finalString;\r
243         }\r
244     };\r
245 \r
246 \r
247     var getBooleanListHtml = function(parameter){\r
248         var html = "";\r
249 \r
250     };\r
251 \r
252     var getOptionListHtml = function(parameter) {\r
253 \r
254         var html = "";\r
255 \r
256         if (!angular.isArray(parameter.optionList)\r
257             || parameter.optionList.length === 0) {\r
258             return "";\r
259         }\r
260 \r
261         if (UtilityService.hasContents(parameter.prompt)) {\r
262                 html += "<option value=''>" + parameter.prompt + "</option>";\r
263         }\r
264 \r
265         for (var i = 0; i < parameter.optionList.length; i++) {\r
266             var option = parameter.optionList[i];\r
267             var name = option.name;\r
268             var value = "";\r
269             if (option.id === undefined) {\r
270                 value = option.name;\r
271             } else {\r
272                 if (name === undefined) {\r
273                     name = option.id;\r
274                 }\r
275                 value = option.id;\r
276             }\r
277             html += getOptionHtml(option.isPermitted, option.isDataLoading, value, name, parameter);\r
278         }\r
279         return html;\r
280     };\r
281 \r
282     function getOptionHtml(isPermitted, isDefault, value, name, parameter) {\r
283         var html = "";\r
284         if (isDefault === undefined || isDefault === false )  {\r
285             if(isPermitted)\r
286                 html = "<option class='" + parameter.id + "Option' value='" + value + "'>" + name + "</option>";\r
287             else {\r
288                 html = "<option class='" + parameter.id + "Option' value='" + value + "' disabled>" + name + "</option>";\r
289             }\r
290         }\r
291         else {\r
292             if(isPermitted)\r
293                 html = "<option class='" + parameter.id + "Option' value='" + value + "'>" + "' selected>"  + name + "</option>";\r
294             else {\r
295                 html = "<option class='" + parameter.id + "Option' value='" + value + "' disabled>" + "' selected>"  + name + "</option>";\r
296             }\r
297         }\r
298         return html;\r
299     }\r
300 \r
301     var getParameter = function(element, expectedId) {\r
302         var id = $(element).attr("parameter-id");\r
303         if (!id || (expectedId !== undefined && expectedId !== id)) {\r
304             return undefined;\r
305         }\r
306         var parameter = {\r
307             id : id\r
308         };\r
309         if ($(element).prop("type") === "checkbox") {\r
310             parameter.value = $(element).prop("checked");\r
311         }else if ($(element).prop("type") === "file") {\r
312             parameter.value = $('#'+id).attr("value");\r
313 \r
314         } else {\r
315             if ($(element).prop("type") === "text") {\r
316                 $(element).val($(element).val().trim());\r
317             }\r
318             parameter.value = $(element).val();\r
319         }\r
320         if ($(element).prop("selectedIndex") === undefined) {\r
321             parameter.selectedIndex = -1;\r
322         } else {\r
323             parameter.selectedIndex = $(element).prop("selectedIndex");\r
324             if (UtilityService.hasContents($(element).attr("prompt"))) {\r
325                 parameter.selectedIndex--;\r
326             }\r
327         }\r
328         return parameter;\r
329     };\r
330 \r
331     var getRequiredField = function(element) {\r
332         if($(element).is("multiselect")) {\r
333             if(!$(element).find(".active").text().trim()) {\r
334                 return '"' + $(element).attr("parameter-name") + '"';\r
335             }\r
336         }\r
337         else {\r
338             if ($(element).prop("type") === "text") {\r
339                 $(element).val($(element).val().trim());\r
340             }\r
341             if ($(element).val() === "" || $(element).val() === null) {\r
342                 return '"' + $(element).attr("parameter-name") + '"';\r
343             }\r
344         }\r
345         return "";\r
346     };\r
347 \r
348     var callback = function(element, scope) {\r
349         scope.callback({\r
350             id : $(element).attr("parameter-id")\r
351         });\r
352     };\r
353 \r
354     return {\r
355         restrict : "EA",\r
356         replace  : true,\r
357         template : "<div><table style='" + tableStyle + "'></table></div>",\r
358         scope : {\r
359             control : "=",\r
360             callback : "&"\r
361         },\r
362         link : function(scope, element, attrs) {\r
363 \r
364             var control = scope.control || {};\r
365             scope.multiselectModel = {};\r
366 \r
367             scope.getOptionsList = function (parameterId) {\r
368                 return _.find(scope.parameterList, {'id': parameterId})["optionList"];\r
369             };\r
370             control.setList = function(parameterList) {\r
371                 scope.parameterList = parameterList;\r
372                 scope.multiselectModel = {};\r
373                 var html = "";\r
374                 for (var i = 0; i < parameterList.length; i++) {\r
375                     html += getParameterHtml(parameterList[i], attrs.editable);\r
376                 }\r
377                 element.replaceWith($compile(element.html(html))(scope));\r
378 \r
379                 element.find("input, select").unbind("change.namespace1");\r
380                 element.find("input, select").bind("change.namespace1", function() {\r
381                     callback(this, scope);\r
382                 });\r
383             }\r
384 \r
385             control.updateList = function(parameterList) {\r
386                 element.find("input, select").each(\r
387                     function() {\r
388                         for (var i = 0; i < parameterList.length; i++) {\r
389                             if (parameterList[i].id === $(this).attr(\r
390                                     "parameter-id")) {\r
391                                 updateParameter(parameterList[i], this,\r
392                                     attrs.editable);\r
393                             }\r
394                         }\r
395                     });\r
396                 element.find("input, select").unbind("change.namespace2");\r
397                 element.find("input, select").bind("change.namespace2", function() {\r
398                     callback(this, scope);\r
399                 });\r
400             }\r
401 \r
402             control.getList = function(expectedId) {\r
403                 var parameterList = new Array();\r
404                 element.find("input, select").each(function() {\r
405                     var parameter = getParameter(this, expectedId);\r
406                     if (parameter !== undefined) {\r
407                         parameterList.push(parameter);\r
408                     }\r
409                 });\r
410                 angular.forEach(scope.multiselectModel, function(value, key) {\r
411                     parameterList.push({id: key, value: value});\r
412                 });\r
413                 return parameterList;\r
414             }\r
415 \r
416             control.getRequiredFields = function() {\r
417                 var requiredFields = "";\r
418                 var count = 0;\r
419                 element.find("input, select, multiselect").each(function() {\r
420                     if ($(this).attr("is-required") === "true") {\r
421                         var requiredField = getRequiredField(this);\r
422                         if (requiredField !== "") {\r
423                             if (++count == 1) {\r
424                                 requiredFields = requiredField;\r
425                             }\r
426                         }\r
427                     }\r
428                 });\r
429                 if (--count <= 0) {\r
430                     return requiredFields;\r
431                 } else if (count == 1) {\r
432                     return requiredFields + " and 1 other field";\r
433                 } else {\r
434                     return requiredFields + " and " + count + " other fields";\r
435                 }\r
436             }\r
437         }\r
438     }\r
439 }\r
440 \r
441 appDS2.directive('parameterBlock', [ "$log", "PARAMETER", "UtilityService", "$compile",\r
442     parameterBlockDirective ]);\r
443 \r
444 \r
445 appDS2.directive('onlyIntegers', function () {\r
446     return  {\r
447         restrict: 'A',\r
448         link: function (scope, elm, attrs, ctrl) {\r
449             elm.on('keydown', function (event) {\r
450                 if(event.shiftKey){event.preventDefault(); return false;}\r
451                 //console.log(event.which);\r
452                 if ([8, 13, 27, 37, 38, 39, 40].indexOf(event.which) > -1) {\r
453                     // backspace, enter, escape, arrows\r
454                     return true;\r
455                 } else if (event.which >= 49 && event.which <= 57) {\r
456                     // numbers\r
457                     return true;\r
458                 } else if (event.which >= 96 && event.which <= 105) {\r
459                     // numpad number\r
460                     return true;\r
461                 }\r
462                 // else if ([110, 190].indexOf(event.which) > -1) {\r
463                 //     // dot and numpad dot\r
464                 //     return true;\r
465                 // }\r
466                 else {\r
467                     event.preventDefault();\r
468                     return false;\r
469                 }\r
470             });\r
471         }\r
472     }\r
473 });\r
474 \r
475 appDS2.directive('onlyFloat', function () {\r
476     return  {\r
477         restrict: 'A',\r
478         link: function (scope, elm, attrs, ctrl) {\r
479             elm.on('keydown', function (event) {\r
480                 if ([110, 190].indexOf(event.which) > -1) {\r
481                     // dot and numpad dot\r
482                     event.preventDefault();\r
483                     return true;\r
484                 }\r
485                 else{\r
486                     return false;\r
487                 }\r
488             });\r
489         }\r
490     }\r
491 });\r