YangUI Controllers Split
[dlux.git] / modules / common-yangutils-resources / src / main / resources / yangutils / listfiltering.services.js
1 define(['common/yangutils/listfiltering.module'], function (listFiltering) {\r
2 \r
3     listFiltering.factory('nodeWrapperForFilter', function(constants, filterConstants) {\r
4         nodeWrapperForFilter = {};\r
5 \r
6         nodeWrapperForFilter.init = function(node){\r
7 \r
8             node.childrenFilterConditions = function (children){\r
9                 var allowedNodeTypesForFilter = filterConstants.ALLOWED_NODE_TYPES_FOR_FILTER,\r
10                     conditionTypes = function(item){\r
11                         return allowedNodeTypesForFilter.some(function(elem){\r
12                             return elem === item.type;\r
13                     });},\r
14                     conditionEmptyChildren = function(item){\r
15                         return item.children.some(function(child){\r
16                             return (child.type !== 'leaf-list' && child.type !== 'list');\r
17                     });},\r
18                     conditionChildDescription = function(item){\r
19                         return !(item.children.every(function(childDes){\r
20                             return childDes.type === 'description';\r
21                     }));};\r
22 \r
23                 return children.filter(function(item){\r
24                     if(item.parent.type === 'leaf' || item.parent.parent.type === 'leaf'){\r
25                         return true;\r
26                     }else{\r
27                         return conditionTypes(item) && conditionEmptyChildren(item) && conditionChildDescription(item);\r
28                     }\r
29                 });\r
30             };\r
31 \r
32             node.getChildrenForFilter = function () {\r
33                 return node.childrenFilterConditions(node.getChildren(null,null,constants.NODE_UI_DISPLAY,null));\r
34             };\r
35 \r
36             node.deepCopyForFilter = function (additionalProperties) {\r
37                 var copy = node.getCleanCopy(),\r
38                     self = this,\r
39                     allowedLeafTypesForFilter = filterConstants.ALLOWED_LEAF_TYPES_FOR_FILTER,\r
40 \r
41                     addFilterProps = function(childrenArray){\r
42                         if(childrenArray.type === 'leaf' && childrenArray.children && childrenArray.children.length){\r
43                             if(childrenArray.children.some(function(item){\r
44                                 return item.type === 'type' && allowedLeafTypesForFilter.indexOf(item.label) !== -1;\r
45                             })){\r
46                                 childrenArray['filterType'] = '=';\r
47                             }\r
48                             if(childrenArray.children.some(function(item){\r
49                                 return item.type === 'type' && item.label === 'bits';\r
50                             })){\r
51                                 childrenArray['filterBitsValue'] = '';\r
52                             }\r
53                             if(childrenArray.children.some(function(item){\r
54                                 return item.type === 'type' && item.label === 'enumeration';\r
55                             })){\r
56                                 childrenArray['filterSelectboxBitsValue'] = [];\r
57                             }\r
58                         }\r
59                 };\r
60 \r
61                 additionalProperties = additionalProperties || ['pathString'];\r
62 \r
63                 additionalProperties.forEach(function(prop) {\r
64                     if (prop !== 'children' && self.hasOwnProperty(prop) && copy.hasOwnProperty(prop) === false) {\r
65                         copy[prop] = self[prop];\r
66                     }\r
67                 });\r
68 \r
69                 this.childrenFilterConditions(this.children).forEach(function (child) {\r
70                     var childCopy = null;\r
71                     if(child.type === 'leaf'){\r
72                         childCopy = child.deepCopy();\r
73                     }else{\r
74                         nodeWrapperForFilter.init(child);\r
75                         childCopy = child.deepCopyForFilter();\r
76                     }\r
77 \r
78                     childCopy.parent = copy;\r
79 \r
80                     addFilterProps(childCopy);\r
81 \r
82                     copy.children.push(childCopy);\r
83                 });\r
84 \r
85                 addFilterProps(copy);\r
86 \r
87                 return copy;\r
88             };\r
89         };\r
90 \r
91         nodeWrapperForFilter.wrapForFilter = function(node) {\r
92 \r
93             var comparePropToElemByName = function (propName, elemName) {\r
94                     return (propName.indexOf(':') > -1 ? propName.split(':')[1] : propName) === elemName; //TODO also check by namespace - redundancy?\r
95                 },\r
96 \r
97                 wrapperFilter = {\r
98 \r
99                     wrapFilter: function (node) {\r
100                         if (this.hasOwnProperty(node.type)) {\r
101                             this[node.type](node);\r
102                         }\r
103                     },\r
104 \r
105                     wrapAllFilter: function (node) {\r
106                         var self = this;\r
107                         self.wrapFilter(node);\r
108                         node.children.forEach(function (child) {\r
109                             self.wrapAllFilter(child);\r
110                         });\r
111                     },\r
112 \r
113                     leaf: function (node) {\r
114                         var auxBuildRequest = node['buildRequest'],\r
115                             auxFill = node['fill'],\r
116                             auxClear = node['clear'],\r
117                             fnToString = function (string) {\r
118                                 var valueStr = '';\r
119                                 try {\r
120                                     valueStr = string.toString();\r
121                                 } catch (e) {\r
122                                     console.warn('cannot convert value', node.value);\r
123                                 }\r
124                                 return valueStr;\r
125                             };\r
126 \r
127                         node.expandedBits = false;\r
128 \r
129                         node.filterRangeFrom = '';\r
130                         node.filterRangeTo = '';\r
131 \r
132                         node.buildRequest = function (builder, req) {\r
133                             auxBuildRequest(builder, req);\r
134                             var valueStr = '';\r
135                             valueStr = fnToString(node.value);\r
136 \r
137                             filterTypeArray = {\r
138                                                 '=': function(element,filterValue,i){\r
139                                                         return element ? element[i] === filterValue : false;\r
140                                                     },\r
141                                                 '>': function(element,filterValue,i){\r
142                                                         return element ? element[i] > filterValue : false;\r
143                                                     },\r
144                                                 '>=': function(element,filterValue,i){\r
145                                                         return element ? element[i] >= filterValue : false;\r
146                                                     },\r
147                                                 '<': function(element,filterValue,i){\r
148                                                         return element ? element[i] < filterValue : false;\r
149                                                     },\r
150                                                 '<=': function(element,filterValue,i){\r
151                                                         return element ? element[i] <= filterValue : false;\r
152                                                     },\r
153                                                 'contains': function(element,filterValue,i){\r
154                                                         return  element ? element[i] && element[i].indexOf(filterValue) > -1 : false;\r
155                                                     },\r
156                                                 'regExp':  function(element,filterValue,i){\r
157                                                         testRegExp = function (patternString, nodeValue) {\r
158                                                             var pattern = new RegExp(patternString);\r
159                                                             return pattern.test(nodeValue);\r
160                                                         };\r
161                                                     return  element ? testRegExp(filterValue,element[i]) : false;\r
162                                                 },\r
163                                                 'range': function(element,from,to,i){\r
164                                                     if(from && to){\r
165                                                         return element ? element[i] <= to && element[i] >= from : false;\r
166                                                     }else if(from){\r
167                                                         return element ? element[i] >= from : false;\r
168                                                     }else{\r
169                                                         return element ? element[i] <= to : false;\r
170                                                     }\r
171                                                 }};\r
172 \r
173                             if (valueStr || (node.filterBitsValue && node.filterBitsValue !== '') || (node.filterSelectboxBitsValue && node.filterSelectboxBitsValue.length) || \r
174                                 (node.filterRangeFrom && node.filterRangeFrom !==  '') || (node.filterRangeTo && node.filterRangeTo !==  '')){\r
175 \r
176                                 reqFilter = {};\r
177 \r
178                                 if(node.filterSelectboxBitsValue && node.filterSelectboxBitsValue.length){ \r
179                                     reqFilter.selectboxBitsValue = node.filterSelectboxBitsValue;\r
180                                     reqFilter.getResult = function(element,filterValue,i){\r
181                                         var selectSomeFun = function(filterSelectboxBitsValue,el){\r
182                                             return filterSelectboxBitsValue.some(function(item,$index){\r
183                                                 return item === el;\r
184                                             });\r
185                                         };\r
186                                         return element[i] && selectSomeFun(filterValue,element[i]);\r
187                                     };\r
188                                 }else{\r
189                                     if(node.filterBitsValue && node.filterBitsValue !== ''){\r
190                                         reqFilter.bitsValue = node.filterBitsValue;\r
191                                     }else{\r
192                                         reqFilter.value = valueStr;\r
193                                     }\r
194 \r
195                                     if(node.filterType){\r
196                                         reqFilter.filterType = node.filterType;\r
197                                     }else{\r
198                                         reqFilter.filterType = '=';\r
199                                     }\r
200 \r
201                                     if(node.filterRangeFrom){\r
202                                         reqFilter.filterRangeFrom = node.filterRangeFrom;\r
203                                     }\r
204 \r
205 \r
206                                     if(node.filterRangeTo){\r
207                                         reqFilter.filterRangeTo = node.filterRangeTo;\r
208                                     }\r
209 \r
210                                     reqFilter.getFilterResult = filterTypeArray;\r
211                                 }\r
212 \r
213                                 builder.insertPropertyToObj(req, node.label, reqFilter);\r
214 \r
215                                 return true;\r
216                             }\r
217                             return false;\r
218                         };\r
219 \r
220                         node.fill = function (name, data) {\r
221                             if(data){\r
222                                 if(data.hasOwnProperty('value')){\r
223                                     auxFill(name, data.value);\r
224                                 }\r
225                                 var match = '';\r
226 \r
227                                 if(data.hasOwnProperty('filterType')){\r
228                                     match = comparePropToElemByName(name, node.label);\r
229                                     if(match){\r
230                                         node.filterType = data.filterType;\r
231                                     }\r
232                                 }\r
233                                 if(data.hasOwnProperty('bitsValue')){\r
234                                     match = comparePropToElemByName(name, node.label);\r
235                                     if(match){\r
236                                         node.filterBitsValue = data.bitsValue;\r
237                                     }\r
238                                 }\r
239                                 if(data.hasOwnProperty('selectboxBitsValue')){\r
240                                     match = comparePropToElemByName(name, node.label);\r
241                                     if(match){\r
242                                         node.filterSelectboxBitsValue = data.selectboxBitsValue;\r
243                                     }\r
244                                 }\r
245                                 if(data.hasOwnProperty('filterRangeFrom')){\r
246                                     match = comparePropToElemByName(name, node.label);\r
247                                     if(match){\r
248                                         node.filterRangeFrom = data.filterRangeFrom;\r
249                                     }\r
250                                 }\r
251                                 if(data.hasOwnProperty('filterRangeTo')){\r
252                                     match = comparePropToElemByName(name, node.label);\r
253                                     if(match){\r
254                                         node.filterRangeTo = data.filterRangeTo;\r
255                                     }\r
256                                 }\r
257                             }else{\r
258                                 console.error('fill data are empty');\r
259                             }\r
260                         };\r
261 \r
262                         node.clear = function () {\r
263                             auxClear();\r
264                             node.value = '';\r
265 \r
266                             if(node.filterType){\r
267                                 node.filterType = '=';\r
268                             }\r
269                             if(node.filterBitsValue){\r
270                                 node.filterBitsValue = '';\r
271                             }\r
272                             if(node.filterSelectboxBitsValue){\r
273                                 node.filterSelectboxBitsValue = [];\r
274                             }\r
275                             if(node.filterRangeFrom){\r
276                                 node.filterRangeFrom = '';\r
277                             }\r
278                             if(node.filterRangeTo){\r
279                                 node.filterRangeTo = '';\r
280                             }\r
281                         };\r
282 \r
283                     },\r
284 \r
285                     type: function (node) {\r
286                     },\r
287 \r
288                     length: function (node) {\r
289                     },\r
290 \r
291                     range: function (node) {\r
292                     },\r
293 \r
294                     pattern: function (node) {\r
295                     },\r
296 \r
297                     container: function (node) {\r
298                     },\r
299 \r
300                     rpc: function (node) {\r
301                     },\r
302 \r
303                     input: function (node) {\r
304                     },\r
305 \r
306                     output: function (node) {\r
307                     },\r
308 \r
309                     case: function (node) {\r
310                     },\r
311 \r
312                     choice: function (node) {\r
313                     },\r
314 \r
315                     'leaf-list': function (node) {\r
316                     },\r
317 \r
318                     key: function (node) {\r
319                     },\r
320 \r
321                     list: function (node) {\r
322 \r
323                     },\r
324 \r
325                     _listElem: function (node) {\r
326                     }\r
327                 };\r
328 \r
329             wrapperFilter.wrapAllFilter(node);\r
330         };\r
331 \r
332 \r
333         return nodeWrapperForFilter;\r
334     });\r
335 \r
336     listFiltering.factory('listFiltering', function (nodeWrapperForFilter, reqBuilder) {\r
337 \r
338         var getNodePathInStructure = function (filterRootNode,node) {\r
339                 var iterator = -1,\r
340                     findNodeInStructure = function (currentParentStructure){\r
341                         if(currentParentStructure.children.length && currentParentStructure.type !== 'leaf'){  \r
342                             if(!(currentParentStructure.children.some(function(element){ return element === node; }))){\r
343                                 currentParentStructure.children.forEach(function(child,index){\r
344                                     checkHasSearchedNode(child,node);\r
345                                 });\r
346                             }else{\r
347                                 wasFound = true;\r
348                             }\r
349                         }\r
350                     },\r
351                     checkHasSearchedNode = function (currentParent) {\r
352                         if(currentParent === node){\r
353                             wasFound = true;\r
354                         }else{\r
355                             if(currentParent.actElemStructure){\r
356                                 findNodeInStructure(currentParent.actElemStructure);\r
357                             }else{\r
358                                 findNodeInStructure(currentParent);\r
359                             }\r
360                         }\r
361                     },\r
362                     getIndexOfSearchedNode = function (parentNodeStructure) {\r
363                         parentNodeStructure.children.forEach(function(elem,index){\r
364                                 wasFound = false;\r
365                                 checkHasSearchedNode(elem,node);\r
366                                 if(wasFound){\r
367                                     node.searchedPath.push(index);\r
368                                 }\r
369                             });    \r
370                         if(parentNodeStructure.children[node.searchedPath[iterator]] !== node){\r
371                             getSearchedPath(parentNodeStructure.children[node.searchedPath[iterator]]);\r
372                         }\r
373                     },\r
374                     getSearchedPath = function(parentNode){\r
375                         iterator++;\r
376                         if(parentNode.actElemStructure){\r
377                             getIndexOfSearchedNode(parentNode.actElemStructure);\r
378                         }else{\r
379                             getIndexOfSearchedNode(parentNode);\r
380                         }\r
381                     };\r
382 \r
383             if(filterRootNode !== node){\r
384                 getSearchedPath(filterRootNode);\r
385             }\r
386         },\r
387 \r
388         clearFilterNodes = function(node) {\r
389             node.referenceNode.filterNodes.forEach(function(filterNode){\r
390                 filterNode.clear();\r
391             });\r
392         },\r
393 \r
394         loadFilterNodes = function (node) {\r
395             var fillFuc = function(fillNods, prop, filVal){\r
396                 fillNods.forEach(function(filterNode){\r
397                     filterNode.fill(prop, filVal[prop]);\r
398                 });\r
399             };\r
400 \r
401             if(node.referenceNode.filters[node.currentFilter].filteredValues){\r
402                 node.referenceNode.filters[node.currentFilter].filteredValues.forEach(function(item){\r
403                     for (var prop in item) {\r
404                         fillFuc(node.referenceNode.filterNodes, prop, item);\r
405                     }\r
406                 });\r
407             }\r
408         },\r
409 \r
410         getFilterResult = function(element, filterValue, node){\r
411             for (var i in filterValue){\r
412                 if(!filterValue[i].hasOwnProperty('value') && !filterValue[i].hasOwnProperty('selectboxBitsValue') && !filterValue[i].hasOwnProperty('bitsValue') &&\r
413                 !filterValue[i].hasOwnProperty('filterRangeFrom') && !filterValue[i].hasOwnProperty('filterRangeTo')){\r
414                     getFilterResult(element[i],filterValue[i]);\r
415                 }else{\r
416                      if(filterValue[i].selectboxBitsValue && filterValue[i].selectboxBitsValue.length){\r
417                         filterResult = filterValue[i].getResult(element,filterValue[i].selectboxBitsValue,i);\r
418                     }else{\r
419                         if((filterValue[i].filterRangeFrom && filterValue[i].filterRangeFrom !== '') || (filterValue[i].filterRangeTo && filterValue[i].filterRangeTo !== '')){\r
420                             filterResult = filterValue[i].getFilterResult[filterValue[i].filterType](element,filterValue[i].filterRangeFrom,filterValue[i].filterRangeTo,i);\r
421                         }else if(filterValue[i].bitsValue && filterValue[i].bitsValue !== ''){\r
422                             filterResult = filterValue[i].getFilterResult[filterValue[i].filterType](element,filterValue[i].bitsValue,i);\r
423                         }else {\r
424                             filterResult = filterValue[i].getFilterResult[filterValue[i].filterType](element,filterValue[i].value,i);\r
425                         }\r
426                     }\r
427                 }\r
428             }\r
429         },\r
430 \r
431         getActElementFilter = function (node) {\r
432             var actData = [];\r
433 \r
434             node.actElemIndex = 0;\r
435             if(node.filteredListData && node.filteredListData.length){\r
436                 actData = node.filteredListData[node.actElemIndex];\r
437             }else{\r
438                 actData = node.listData[node.actElemIndex];\r
439             }\r
440             \r
441             node.actElemStructure.clear();\r
442             for (var prop in actData) {\r
443                 node.actElemStructure.fillListElement(prop, actData[prop]);\r
444             }\r
445         };\r
446 \r
447         listFiltering = {};\r
448 \r
449         listFiltering.removeEmptyFilters = function (node) {\r
450             if(node.referenceNode && node.referenceNode.filters){\r
451                 var wasDeleted = false;\r
452                 node.referenceNode.filters = node.referenceNode.filters.filter(function(filter){\r
453                     if(filter.filteredValues && filter.filteredValues.length){\r
454                         return true;\r
455                     }else{\r
456                         wasDeleted = true;\r
457                         return false;\r
458                     }\r
459                 });\r
460 \r
461                 if(wasDeleted){\r
462                     listFiltering.switchFilter(node,0,true);\r
463                 }\r
464             }\r
465         };\r
466 \r
467         listFiltering.showListFilterWin = function (filterRootNode,node) {\r
468             if(!node.searchedPath.length){\r
469                 getNodePathInStructure(filterRootNode,node);\r
470             }\r
471 \r
472             if(!node.referenceNode){\r
473                 node.referenceNode = filterRootNode;\r
474                 node.searchedPath.forEach(function(elem){\r
475                     node.referenceNode = node.referenceNode.children[elem];\r
476                 });\r
477             }\r
478 \r
479             if(!node.referenceNode.filterNodes.length){\r
480                 nodeWrapperForFilter.init(node);\r
481                 node.referenceNode.filterNodes = node.getNewFilterElement();\r
482             }\r
483 \r
484             if(!(node.referenceNode.filters && node.referenceNode.filters.length)){\r
485                 node.referenceNode.filters.push({name : 'Filter 1 name', active : 1});\r
486             }else{\r
487                 listFiltering.getFilterData(node);\r
488                 listFiltering.removeEmptyFilters(node);\r
489             }\r
490         };\r
491 \r
492         listFiltering.createNewFilter = function (node) {\r
493             node.referenceNode.filters.push({name : 'Filter ' + (node.referenceNode.filters.length+1) + ' name', active : 1});\r
494 \r
495             listFiltering.switchFilter(node,node.referenceNode.filters.length-1);\r
496         };\r
497 \r
498         listFiltering.getFilterData = function (node) {\r
499              node.referenceNode.filters[node.currentFilter].filteredValues = node.referenceNode.filterNodes.map(function(element){\r
500                 var requestData = {};\r
501                 element.buildRequest(reqBuilder, requestData);\r
502                 return requestData;\r
503             }).filter(function(item){\r
504                 return $.isEmptyObject(item) === false;\r
505             });\r
506         };\r
507 \r
508         listFiltering.switchFilter = function (node,showedFilter,fromRemoveEmptyFilters) {\r
509             if(node.referenceNode.filters.length){\r
510                 if(!fromRemoveEmptyFilters){\r
511                     listFiltering.getFilterData(node);\r
512                 }\r
513                 clearFilterNodes(node);\r
514                 node.currentFilter = showedFilter;\r
515                 loadFilterNodes(node);\r
516             }else{\r
517                 node.currentFilter = 0;\r
518             }\r
519         };\r
520 \r
521         listFiltering.applyFilter = function (node) {\r
522             listFiltering.getFilterData(node);\r
523             listFiltering.removeEmptyFilters(node);\r
524 \r
525             node.filteredListData = node.listData.slice().filter(function(element){\r
526                 return node.referenceNode.filters.filter(function(fil){\r
527                         return fil.active === 1;\r
528                     }).some(function(filter){\r
529                         return filter.filteredValues.every(function(filterValue){\r
530                             filterResult = null;\r
531                             getFilterResult(element,filterValue,node);\r
532                             return filterResult;\r
533                         });\r
534                     });\r
535             });\r
536 \r
537             getActElementFilter(node);\r
538             // console.info('applyFilter node',node,'node.referenceNode.filterNodes',node.referenceNode.filterNodes,'node.referenceNode.filters',node.referenceNode.filters);\r
539         };\r
540 \r
541         listFiltering.clearFilterData = function (node, changeAct, filterForClear, removeFilters) {\r
542             if(filterForClear){\r
543                 filterForClear--;\r
544                 if(node.referenceNode.filters.length === 1){\r
545                     node.referenceNode.filters = [];\r
546                     node.referenceNode.filters.push({name : 'Filter 1 name', active : 1});\r
547                     clearFilterNodes(node);\r
548                 }else{\r
549                     node.referenceNode.filters.splice(filterForClear,1);\r
550                     node.currentFilter = 0;\r
551                     clearFilterNodes(node);\r
552                     loadFilterNodes(node);\r
553                 }\r
554             }else{\r
555                 if(removeFilters){\r
556                     node.referenceNode.filters = [];\r
557                     clearFilterNodes(node);\r
558                     node.currentFilter = 0;\r
559                 }else{\r
560                     node.referenceNode.filters.forEach(function(filter){\r
561                         filter.active = 2;\r
562                     });\r
563                     listFiltering.getFilterData(node);\r
564                     listFiltering.removeEmptyFilters(node);\r
565                 }\r
566                 node.filteredListData = [];\r
567             }\r
568 \r
569             if(changeAct){\r
570                 getActElementFilter(node);\r
571             }\r
572 \r
573         };\r
574 \r
575         return listFiltering;\r
576     });\r
577 \r
578     listFiltering.factory('filterConstants', function () {\r
579         return  {\r
580             ADVANCED_FILTERING_TYPES : {'number' : ['=','>','>=','<','<=','range'],'string' : ['=','contains','regExp']},\r
581             ALLOWED_LEAF_TYPES_FOR_FILTER : ['string','uint32','uint8','decimal64','int16','int32','int64','int8','uint16','uint64','union','bits','leafref','identityref'],\r
582             ALLOWED_NODE_TYPES_FOR_FILTER : ['case','choice','container','input','leaf','output','rpc']\r
583         };\r
584     });\r
585 });