Initial commit for OpenECOMP SDN-C OA&M
[sdnc/oam.git] / admportal / public / javascripts / jquery.treegrid.js
1 /*\r
2  * jQuery treegrid Plugin 0.2.0\r
3  * https://github.com/maxazan/jquery-treegrid\r
4  *\r
5  * Copyright 2013, Pomazan Max\r
6  * Licensed under the MIT licenses.\r
7  */\r
8 (function($) {\r
9 \r
10     var methods = {\r
11         /**\r
12          * Initialize tree\r
13          *\r
14          * @param {Object} options\r
15          * @returns {Object[]}\r
16          */\r
17         initTree: function(options) {\r
18             var settings = $.extend({}, this.treegrid.defaults, options);\r
19             return this.each(function() {\r
20                 var $this = $(this);\r
21                 $this.treegrid('setTreeContainer', $(this));\r
22                 $this.treegrid('setSettings', settings);\r
23                 settings.getRootNodes.apply(this, [$(this)]).treegrid('initNode', settings);\r
24                 $this.treegrid('getRootNodes').treegrid('render');\r
25             });\r
26         },\r
27         /**\r
28          * Initialize node\r
29          *\r
30          * @param {Object} settings\r
31          * @returns {Object[]}\r
32          */\r
33         initNode: function(settings) {\r
34             return this.each(function() {\r
35                 var $this = $(this);\r
36                 $this.treegrid('setTreeContainer', settings.getTreeGridContainer.apply(this));\r
37                 $this.treegrid('getChildNodes').treegrid('initNode', settings);\r
38                 $this.treegrid('initExpander').treegrid('initIndent').treegrid('initEvents').treegrid('initState').treegrid('initChangeEvent').treegrid("initSettingsEvents");\r
39             });\r
40         },\r
41         initChangeEvent: function() {\r
42             var $this = $(this);\r
43             //Save state on change\r
44             $this.on("change", function() {\r
45                 var $this = $(this);\r
46                 $this.treegrid('render');\r
47                 if ($this.treegrid('getSetting', 'saveState')) {\r
48                     $this.treegrid('saveState');\r
49                 }\r
50             });\r
51             return $this;\r
52         },\r
53         /**\r
54          * Initialize node events\r
55          *\r
56          * @returns {Node}\r
57          */\r
58         initEvents: function() {\r
59             var $this = $(this);\r
60             //Default behavior on collapse\r
61             $this.on("collapse", function() {\r
62                 var $this = $(this);\r
63                 $this.removeClass('treegrid-expanded');\r
64                 $this.addClass('treegrid-collapsed');\r
65             });\r
66             //Default behavior on expand\r
67             $this.on("expand", function() {\r
68                 var $this = $(this);\r
69                 $this.removeClass('treegrid-collapsed');\r
70                 $this.addClass('treegrid-expanded');\r
71             });\r
72 \r
73             return $this;\r
74         },\r
75         /**\r
76          * Initialize events from settings\r
77          *\r
78          * @returns {Node}\r
79          */\r
80         initSettingsEvents: function() {\r
81             var $this = $(this);\r
82             //Save state on change\r
83             $this.on("change", function() {\r
84                 var $this = $(this);\r
85                 if (typeof($this.treegrid('getSetting', 'onChange')) === "function") {\r
86                     $this.treegrid('getSetting', 'onChange').apply($this);\r
87                 }\r
88             });\r
89             //Default behavior on collapse\r
90             $this.on("collapse", function() {\r
91                 var $this = $(this);\r
92                 if (typeof($this.treegrid('getSetting', 'onCollapse')) === "function") {\r
93                     $this.treegrid('getSetting', 'onCollapse').apply($this);\r
94                 }\r
95             });\r
96             //Default behavior on expand\r
97             $this.on("expand", function() {\r
98                 var $this = $(this);\r
99                 if (typeof($this.treegrid('getSetting', 'onExpand')) === "function") {\r
100                     $this.treegrid('getSetting', 'onExpand').apply($this);\r
101                 }\r
102 \r
103             });\r
104 \r
105             return $this;\r
106         },\r
107         /**\r
108          * Initialize expander for node\r
109          *\r
110          * @returns {Node}\r
111          */\r
112         initExpander: function() {\r
113             var $this = $(this);\r
114             var cell = $this.find('td').get($this.treegrid('getSetting', 'treeColumn'));\r
115             var tpl = $this.treegrid('getSetting', 'expanderTemplate');\r
116             var expander = $this.treegrid('getSetting', 'getExpander').apply(this);\r
117             if (expander) {\r
118                 expander.remove();\r
119             }\r
120             $(tpl).prependTo(cell).click(function() {\r
121                 $($(this).closest('tr')).treegrid('toggle');\r
122             });\r
123             return $this;\r
124         },\r
125         /**\r
126          * Initialize indent for node\r
127          *\r
128          * @returns {Node}\r
129          */\r
130         initIndent: function() {\r
131             var $this = $(this);\r
132             $this.find('.treegrid-indent').remove();\r
133             var tpl = $this.treegrid('getSetting', 'indentTemplate');\r
134             var expander = $this.find('.treegrid-expander');\r
135             var depth = $this.treegrid('getDepth');\r
136             for (var i = 0; i < depth; i++) {\r
137                 $(tpl).insertBefore(expander);\r
138             }\r
139             return $this;\r
140         },\r
141         /**\r
142          * Initialise state of node\r
143          *\r
144          * @returns {Node}\r
145          */\r
146         initState: function() {\r
147             var $this = $(this);\r
148             if ($this.treegrid('getSetting', 'saveState') && !$this.treegrid('isFirstInit')) {\r
149                 $this.treegrid('restoreState');\r
150             } else {\r
151                 if ($this.treegrid('getSetting', 'initialState') === "expanded") {\r
152                     $this.treegrid('expand');\r
153                 } else {\r
154                     $this.treegrid('collapse');\r
155                 }\r
156             }\r
157             return $this;\r
158         },\r
159         /**\r
160          * Return true if this tree was never been initialised\r
161          *\r
162          * @returns {Boolean}\r
163          */\r
164         isFirstInit: function() {\r
165             var tree = $(this).treegrid('getTreeContainer');\r
166             if (tree.data('first_init') === undefined) {\r
167                 tree.data('first_init', $.cookie(tree.treegrid('getSetting', 'saveStateName')) === undefined);\r
168             }\r
169             return tree.data('first_init');\r
170         },\r
171         /**\r
172          * Save state of current node\r
173          *\r
174          * @returns {Node}\r
175          */\r
176         saveState: function() {\r
177             var $this = $(this);\r
178             if ($this.treegrid('getSetting', 'saveStateMethod') === 'cookie') {\r
179 \r
180                 var stateArrayString = $.cookie($this.treegrid('getSetting', 'saveStateName')) || '';\r
181                 var stateArray = (stateArrayString === '' ? [] : stateArrayString.split(','));\r
182                 var nodeId = $this.treegrid('getNodeId');\r
183 \r
184                 if ($this.treegrid('isExpanded')) {\r
185                     if ($.inArray(nodeId, stateArray) === -1) {\r
186                         stateArray.push(nodeId);\r
187                     }\r
188                 } else if ($this.treegrid('isCollapsed')) {\r
189                     if ($.inArray(nodeId, stateArray) !== -1) {\r
190                         stateArray.splice($.inArray(nodeId, stateArray), 1);\r
191                     }\r
192                 }\r
193                 $.cookie($this.treegrid('getSetting', 'saveStateName'), stateArray.join(','));\r
194             }\r
195             return $this;\r
196         },\r
197         /**\r
198          * Restore state of current node.\r
199          *\r
200          * @returns {Node}\r
201          */\r
202         restoreState: function() {\r
203             var $this = $(this);\r
204             if ($this.treegrid('getSetting', 'saveStateMethod') === 'cookie') {\r
205                 var stateArray = $.cookie($this.treegrid('getSetting', 'saveStateName')).split(',');\r
206                 if ($.inArray($this.treegrid('getNodeId'), stateArray) !== -1) {\r
207                     $this.treegrid('expand');\r
208                 } else {\r
209                     $this.treegrid('collapse');\r
210                 }\r
211 \r
212             }\r
213             return $this;\r
214         },\r
215         /**\r
216          * Method return setting by name\r
217          *\r
218          * @param {type} name\r
219          * @returns {unresolved}\r
220          */\r
221         getSetting: function(name) {\r
222             if (!$(this).treegrid('getTreeContainer')) {\r
223                 return null;\r
224             }\r
225             return $(this).treegrid('getTreeContainer').data('settings')[name];\r
226         },\r
227         /**\r
228          * Add new settings\r
229          *\r
230          * @param {Object} settings\r
231          */\r
232         setSettings: function(settings) {\r
233             $(this).treegrid('getTreeContainer').data('settings', settings);\r
234         },\r
235         /**\r
236          * Return tree container\r
237          *\r
238          * @returns {HtmlElement}\r
239          */\r
240         getTreeContainer: function() {\r
241             return $(this).data('treegrid');\r
242         },\r
243         /**\r
244          * Set tree container\r
245          *\r
246          * @param {HtmlE;ement} container\r
247          */\r
248         setTreeContainer: function(container) {\r
249             return $(this).data('treegrid', container);\r
250         },\r
251         /**\r
252          * Method return all root nodes of tree.\r
253          *\r
254          * Start init all child nodes from it.\r
255          *\r
256          * @returns {Array}\r
257          */\r
258         getRootNodes: function() {\r
259             return $(this).treegrid('getSetting', 'getRootNodes').apply(this, [$(this).treegrid('getTreeContainer')]);\r
260         },\r
261         /**\r
262          * Method return all nodes of tree.\r
263          *\r
264          * @returns {Array}\r
265          */\r
266         getAllNodes: function() {\r
267             return $(this).treegrid('getSetting', 'getAllNodes').apply(this, [$(this).treegrid('getTreeContainer')]);\r
268         },\r
269         /**\r
270          * Mthod return true if element is Node\r
271          *\r
272          * @returns {String}\r
273          */\r
274         isNode: function() {\r
275             return $(this).treegrid('getNodeId') !== null;\r
276         },\r
277         /**\r
278          * Mthod return id of node\r
279          *\r
280          * @returns {String}\r
281          */\r
282         getNodeId: function() {\r
283             if ($(this).treegrid('getSetting', 'getNodeId') === null) {\r
284                 return null;\r
285             } else {\r
286                 return $(this).treegrid('getSetting', 'getNodeId').apply(this);\r
287             }\r
288         },\r
289         /**\r
290          * Method return parent id of node or null if root node\r
291          *\r
292          * @returns {String}\r
293          */\r
294         getParentNodeId: function() {\r
295             return $(this).treegrid('getSetting', 'getParentNodeId').apply(this);\r
296         },\r
297         /**\r
298          * Method return parent node or null if root node\r
299          *\r
300          * @returns {Object[]}\r
301          */\r
302         getParentNode: function() {\r
303             if ($(this).treegrid('getParentNodeId') === null) {\r
304                 return null;\r
305             } else {\r
306                 return $(this).treegrid('getSetting', 'getNodeById').apply(this, [$(this).treegrid('getParentNodeId'), $(this).treegrid('getTreeContainer')]);\r
307             }\r
308         },\r
309         /**\r
310          * Method return array of child nodes or null if node is leaf\r
311          *\r
312          * @returns {Object[]}\r
313          */\r
314         getChildNodes: function() {\r
315             return $(this).treegrid('getSetting', 'getChildNodes').apply(this, [$(this).treegrid('getNodeId'), $(this).treegrid('getTreeContainer')]);\r
316         },\r
317         /**\r
318          * Method return depth of tree.\r
319          *\r
320          * This method is needs for calculate indent\r
321          *\r
322          * @returns {Number}\r
323          */\r
324         getDepth: function() {\r
325             if ($(this).treegrid('getParentNode') === null) {\r
326                 return 0;\r
327             }\r
328             return $(this).treegrid('getParentNode').treegrid('getDepth') + 1;\r
329         },\r
330         /**\r
331          * Method return true if node is root\r
332          *\r
333          * @returns {Boolean}\r
334          */\r
335         isRoot: function() {\r
336             return $(this).treegrid('getDepth') === 0;\r
337         },\r
338         /**\r
339          * Method return true if node has no child nodes\r
340          *\r
341          * @returns {Boolean}\r
342          */\r
343         isLeaf: function() {\r
344             return $(this).treegrid('getChildNodes').length === 0;\r
345         },\r
346         /**\r
347          * Method return true if node last in branch\r
348          *\r
349          * @returns {Boolean}\r
350          */\r
351         isLast: function() {\r
352             if ($(this).treegrid('isNode')) {\r
353                 var parentNode = $(this).treegrid('getParentNode');\r
354                 if (parentNode === null) {\r
355                     if ($(this).treegrid('getNodeId') === $(this).treegrid('getRootNodes').last().treegrid('getNodeId')) {\r
356                         return true;\r
357                     }\r
358                 } else {\r
359                     if ($(this).treegrid('getNodeId') === parentNode.treegrid('getChildNodes').last().treegrid('getNodeId')) {\r
360                         return true;\r
361                     }\r
362                 }\r
363             }\r
364             return false;\r
365         },\r
366         /**\r
367          * Method return true if node first in branch\r
368          *\r
369          * @returns {Boolean}\r
370          */\r
371         isFirst: function() {\r
372             if ($(this).treegrid('isNode')) {\r
373                 var parentNode = $(this).treegrid('getParentNode');\r
374                 if (parentNode === null) {\r
375                     if ($(this).treegrid('getNodeId') === $(this).treegrid('getRootNodes').first().treegrid('getNodeId')) {\r
376                         return true;\r
377                     }\r
378                 } else {\r
379                     if ($(this).treegrid('getNodeId') === parentNode.treegrid('getChildNodes').first().treegrid('getNodeId')) {\r
380                         return true;\r
381                     }\r
382                 }\r
383             }\r
384             return false;\r
385         },\r
386         /**\r
387          * Return true if node expanded\r
388          *\r
389          * @returns {Boolean}\r
390          */\r
391         isExpanded: function() {\r
392             return $(this).hasClass('treegrid-expanded');\r
393         },\r
394         /**\r
395          * Return true if node collapsed\r
396          *\r
397          * @returns {Boolean}\r
398          */\r
399         isCollapsed: function() {\r
400             return $(this).hasClass('treegrid-collapsed');\r
401         },\r
402         /**\r
403          * Return true if at least one of parent node is collapsed\r
404          *\r
405          * @returns {Boolean}\r
406          */\r
407         isOneOfParentsCollapsed: function() {\r
408             var $this = $(this);\r
409             if ($this.treegrid('isRoot')) {\r
410                 return false;\r
411             } else {\r
412                 if ($this.treegrid('getParentNode').treegrid('isCollapsed')) {\r
413                     return true;\r
414                 } else {\r
415                     return $this.treegrid('getParentNode').treegrid('isOneOfParentsCollapsed');\r
416                 }\r
417             }\r
418         },\r
419         /**\r
420          * Expand node\r
421          *\r
422          * @returns {Node}\r
423          */\r
424         expand: function() {\r
425             if (!this.treegrid('isLeaf') && !this.treegrid("isExpanded")) {\r
426                 this.trigger("expand");\r
427                 this.trigger("change");\r
428                 return this;\r
429             }\r
430             return this;\r
431         },\r
432         /**\r
433          * Expand all nodes\r
434          *\r
435          * @returns {Node}\r
436          */\r
437         expandAll: function() {\r
438             var $this = $(this);\r
439             $this.treegrid('getRootNodes').treegrid('expandRecursive');\r
440             return $this;\r
441         },\r
442         /**\r
443          * Expand current node and all child nodes begin from current\r
444          *\r
445          * @returns {Node}\r
446          */\r
447         expandRecursive: function() {\r
448             return $(this).each(function() {\r
449                 var $this = $(this);\r
450                 $this.treegrid('expand');\r
451                 if (!$this.treegrid('isLeaf')) {\r
452                     $this.treegrid('getChildNodes').treegrid('expandRecursive');\r
453                 }\r
454             });\r
455         },\r
456         /**\r
457          * Collapse node\r
458          *\r
459          * @returns {Node}\r
460          */\r
461         collapse: function() {\r
462             return $(this).each(function() {\r
463                 var $this = $(this);\r
464                 if (!$this.treegrid('isLeaf') && !$this.treegrid("isCollapsed")) {\r
465                     $this.trigger("collapse");\r
466                     $this.trigger("change");\r
467                 }\r
468             });\r
469         },\r
470         /**\r
471          * Collapse all nodes\r
472          *\r
473          * @returns {Node}\r
474          */\r
475         collapseAll: function() {\r
476             var $this = $(this);\r
477             $this.treegrid('getRootNodes').treegrid('collapseRecursive');\r
478             return $this;\r
479         },\r
480         /**\r
481          * Collapse current node and all child nodes begin from current\r
482          *\r
483          * @returns {Node}\r
484          */\r
485         collapseRecursive: function() {\r
486             return $(this).each(function() {\r
487                 var $this = $(this);\r
488                 $this.treegrid('collapse');\r
489                 if (!$this.treegrid('isLeaf')) {\r
490                     $this.treegrid('getChildNodes').treegrid('collapseRecursive');\r
491                 }\r
492             });\r
493         },\r
494         /**\r
495          * Expand if collapsed, Collapse if expanded\r
496          *\r
497          * @returns {Node}\r
498          */\r
499         toggle: function() {\r
500             var $this = $(this);\r
501             if ($this.treegrid('isExpanded')) {\r
502                 $this.treegrid('collapse');\r
503             } else {\r
504                 $this.treegrid('expand');\r
505             }\r
506             return $this;\r
507         },\r
508         /**\r
509          * Rendering node\r
510          *\r
511          * @returns {Node}\r
512          */\r
513         render: function() {\r
514             return $(this).each(function() {\r
515                 var $this = $(this);\r
516                 //if parent colapsed we hidden\r
517                 if ($this.treegrid('isOneOfParentsCollapsed')) {\r
518                     $this.hide();\r
519                 } else {\r
520                     $this.show();\r
521                 }\r
522                 if (!$this.treegrid('isLeaf')) {\r
523                     $this.treegrid('renderExpander');\r
524                     $this.treegrid('getChildNodes').treegrid('render');\r
525                 }\r
526             });\r
527         },\r
528         /**\r
529          * Rendering expander depends on node state\r
530          *\r
531          * @returns {Node}\r
532          */\r
533         renderExpander: function() {\r
534             return $(this).each(function() {\r
535                 var $this = $(this);\r
536                 var expander = $this.treegrid('getSetting', 'getExpander').apply(this);\r
537                 if (expander) {\r
538 \r
539                     if (!$this.treegrid('isCollapsed')) {\r
540                         expander.removeClass($this.treegrid('getSetting', 'expanderCollapsedClass'));\r
541                         expander.addClass($this.treegrid('getSetting', 'expanderExpandedClass'));\r
542                     } else {\r
543                         expander.removeClass($this.treegrid('getSetting', 'expanderExpandedClass'));\r
544                         expander.addClass($this.treegrid('getSetting', 'expanderCollapsedClass'));\r
545                     }\r
546                 } else {\r
547                     $this.treegrid('initExpander');\r
548                     $this.treegrid('renderExpander');\r
549                 }\r
550             });\r
551         }\r
552     };\r
553     $.fn.treegrid = function(method) {\r
554         if (methods[method]) {\r
555             return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));\r
556         } else if (typeof method === 'object' || !method) {\r
557             return methods.initTree.apply(this, arguments);\r
558         } else {\r
559             $.error('Method with name ' + method + ' does not exists for jQuery.treegrid');\r
560         }\r
561     };\r
562     /**\r
563      *  Plugin's default options\r
564      */\r
565     $.fn.treegrid.defaults = {\r
566         initialState: 'expanded',\r
567         saveState: false,\r
568         saveStateMethod: 'cookie',\r
569         saveStateName: 'tree-grid-state',\r
570         expanderTemplate: '<span class="treegrid-expander"></span>',\r
571         indentTemplate: '<span class="treegrid-indent"></span>',\r
572         expanderExpandedClass: 'treegrid-expander-expanded',\r
573         expanderCollapsedClass: 'treegrid-expander-collapsed',\r
574         treeColumn: 0,\r
575         getExpander: function() {\r
576             return $(this).find('.treegrid-expander');\r
577         },\r
578         getNodeId: function() {\r
579             var template = /treegrid-([A-Za-z0-9_-]+)/;\r
580             if (template.test($(this).attr('class'))) {\r
581                 return template.exec($(this).attr('class'))[1];\r
582             }\r
583             return null;\r
584         },\r
585         getParentNodeId: function() {\r
586             var template = /treegrid-parent-([A-Za-z0-9_-]+)/;\r
587             if (template.test($(this).attr('class'))) {\r
588                 return template.exec($(this).attr('class'))[1];\r
589             }\r
590             return null;\r
591         },\r
592         getNodeById: function(id, treegridContainer) {\r
593             var templateClass = "treegrid-" + id;\r
594             return treegridContainer.find('tr.' + templateClass);\r
595         },\r
596         getChildNodes: function(id, treegridContainer) {\r
597             var templateClass = "treegrid-parent-" + id;\r
598             return treegridContainer.find('tr.' + templateClass);\r
599         },\r
600         getTreeGridContainer: function() {\r
601             return $(this).closest('table');\r
602         },\r
603         getRootNodes: function(treegridContainer) {\r
604             var result = $.grep(treegridContainer.find('tr'), function(element) {\r
605                 var classNames = $(element).attr('class');\r
606                 var templateClass = /treegrid-([A-Za-z0-9_-]+)/;\r
607                 var templateParentClass = /treegrid-parent-([A-Za-z0-9_-]+)/;\r
608                 return templateClass.test(classNames) && !templateParentClass.test(classNames);\r
609             });\r
610             return $(result);\r
611         },\r
612         getAllNodes: function(treegridContainer) {\r
613             var result = $.grep(treegridContainer.find('tr'), function(element) {\r
614                 var classNames = $(element).attr('class');\r
615                 var templateClass = /treegrid-([A-Za-z0-9_-]+)/;\r
616                 return templateClass.test(classNames);\r
617             });\r
618             return $(result);\r
619         },\r
620         //Events\r
621         onCollapse: null,\r
622         onExpand: null,\r
623         onChange: null\r
624 \r
625     };\r
626 })(jQuery);\r