[PORTAL-7] Rebase
[portal.git] / ecomp-portal-FE-os / client / src / views / functionalMenu / jqTreeContextMenu.js
1 /*-\r
2  * ================================================================================\r
3  * ECOMP Portal\r
4  * ================================================================================\r
5  * Copyright (C) 2017 AT&T Intellectual Property\r
6  * ================================================================================\r
7  * Licensed under the Apache License, Version 2.0 (the "License");\r
8  * you may not use this file except in compliance with the License.\r
9  * You may obtain a copy of the License at\r
10  * \r
11  *      http://www.apache.org/licenses/LICENSE-2.0\r
12  * \r
13  * Unless required by applicable law or agreed to in writing, software\r
14  * distributed under the License is distributed on an "AS IS" BASIS,\r
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
16  * See the License for the specific language governing permissions and\r
17  * limitations under the License.\r
18  * ================================================================================\r
19  */\r
20 (function ($) {\r
21         if (!$.fn.tree) {\r
22                 throw "Error jqTree is not loaded.";\r
23         }\r
24 \r
25         $.fn.jqTreeContextMenu = function (menuElement, callbacks) {\r
26                 //\r
27                 // TODO:\r
28                 // * Make sure the useContextMenu option is set in jqTree, either complain or set it automatically\r
29                 // * Make menu fade in/out\r
30                 //\r
31                 var self = this;\r
32                 var $el = this;\r
33 \r
34                 // The jQuery object of the menu div.\r
35                 var $menuEl = menuElement;\r
36                 \r
37                 // This hash holds all menu items that should be disabled for a specific node.\r
38                 var nodeToDisabledMenuItems = {};\r
39                 \r
40                 // Hide the menu div.\r
41                 $menuEl.hide();\r
42 \r
43                 // Disable system context menu from beeing displayed.\r
44                 $el.bind("contextmenu", function (e) { \r
45                         e.preventDefault();\r
46                         return false; \r
47                 });\r
48 \r
49                 // Handle the contextmenu event sent from jqTree when user clicks right mouse button.\r
50                 $el.bind('tree.contextmenu', function (event) {\r
51                         var x = event.click_event.pageX;\r
52                         var y = event.click_event.pageY;\r
53                         var yPadding = 5;\r
54                         var xPadding = 5;\r
55                         var menuHeight = $menuEl.height();\r
56                         var menuWidth = $menuEl.width();\r
57                         var windowHeight = $(window).height();\r
58                         var windowWidth = $(window).width();\r
59                         \r
60                         if (menuHeight + y + yPadding > windowHeight) {\r
61                                 // Make sure the whole menu is rendered within the viewport. \r
62                                 y = y - menuHeight;\r
63                         }\r
64                         if (menuWidth + x + xPadding > windowWidth) {\r
65                                 // Make sure the whole menu is rendered within the viewport. \r
66                                 x = x - menuWidth;\r
67                         }\r
68 \r
69                         // Handle disabling and enabling of menu items on specific nodes.\r
70                         if (Object.keys(nodeToDisabledMenuItems).length > 0) {\r
71                                 if (event.node.name in nodeToDisabledMenuItems) {\r
72                                         var nodeName = event.node.name;\r
73                                         var items = nodeToDisabledMenuItems[nodeName];\r
74                                         if (items.length === 0) {\r
75                                                 $menuEl.find('li').addClass('disabled');\r
76                                                 $menuEl.find('li > a').unbind('click');\r
77                                         } else {\r
78                                                 $menuEl.find('li > a').each(function () {\r
79                                                         $(this).closest('li').removeClass('disabled');\r
80                                                         var hrefValue = $(this).attr('href');\r
81                                                         var value = hrefValue.slice(hrefValue.indexOf("#") + 1, hrefValue.length)\r
82                                                         if ($.inArray(value, items) > -1) {\r
83                                                                 $(this).closest('li').addClass('disabled');\r
84                                                                 $(this).unbind('click');\r
85                                                         }\r
86                                                 });     \r
87                                         }\r
88                                 } else {\r
89                                         $menuEl.find('li.disabled').removeClass('disabled');\r
90                                 }\r
91                         }\r
92 \r
93                         // Must call show before we set the offset (offset can not be set on display: none elements).\r
94                         $menuEl.show();\r
95 \r
96                         $menuEl.offset({ left: x, top: y });\r
97 \r
98                         var dismissContextMenu = function () {\r
99                                 $(document).unbind('click.jqtreecontextmenu');\r
100                                 $el.unbind('tree.click.jqtreecontextmenu');\r
101                                 $menuEl.hide();\r
102                         }\r
103                         // Make it possible to dismiss context menu by clicking somewhere in the document.\r
104                         $(document).bind('click.jqtreecontextmenu', function () {\r
105                                 dismissContextMenu();\r
106                         });\r
107 \r
108                         // Dismiss context menu if another node in the tree is clicked.\r
109                         $el.bind('tree.click.jqtreecontextmenu', function (e) {\r
110                                 dismissContextMenu();\r
111                         });\r
112 \r
113                         // Make selection follow the node that was right clicked on.\r
114                         var selectedNode = $el.tree('getSelectedNode');\r
115                         if (selectedNode !== event.node) {\r
116                                 $el.tree('selectNode', event.node);\r
117                         }\r
118 \r
119                         // Handle click on menu items, if it's not disabled.\r
120                         var menuItems = $menuEl.find('li:not(.disabled) a');\r
121                         if (menuItems.length !== 0) {\r
122                                 menuItems.unbind('click');\r
123                                 menuItems.click(function (e) {\r
124                                         e.stopImmediatePropagation();\r
125                                         dismissContextMenu();\r
126                                         var hrefAnchor = e.currentTarget.attributes.href.nodeValue;\r
127                                         var funcKey = hrefAnchor.slice(hrefAnchor.indexOf("#") + 1, hrefAnchor.length)\r
128                                         var callbackFn = callbacks[funcKey];\r
129                                         if (callbackFn) {\r
130                                                 callbackFn(event.node);\r
131                                         }\r
132                                         return false;\r
133                                 });\r
134                         }\r
135                 });\r
136                 \r
137                 this.disable = function () {\r
138                         if (arguments.length === 0) {\r
139                                 // Called as: api.disable()\r
140                                 $menuEl.find('li:not(.disabled)').addClass('disabled');\r
141                                 $menuEl.find('li a').unbind('click');\r
142                                 nodeToDisabledMenuItems = {};\r
143                         } else if (arguments.length === 1) {\r
144                                 // Called as: api.disable(['edit','remove'])\r
145                                 var items = arguments[0];\r
146                                 if (typeof items !== 'object') {\r
147                                         return;\r
148                                 }\r
149                                 $menuEl.find('li > a').each(function () {\r
150                                         var hrefValue = $(this).attr('href');\r
151                                         var value = hrefValue.slice(hrefValue.indexOf("#") + 1, hrefValue.length)\r
152                                         if ($.inArray(value, items) > -1) {\r
153                                                 $(this).closest('li').addClass('disabled');\r
154                                                 $(this).unbind('click');\r
155                                         }\r
156                                 });\r
157                                 nodeToDisabledMenuItems = {};\r
158                         } else if (arguments.length === 2) {\r
159                                 // Called as: api.disable(nodeName, ['edit','remove'])\r
160                                 var nodeName = arguments[0];\r
161                                 var items = arguments[1];\r
162                                 nodeToDisabledMenuItems[nodeName] = items;\r
163                         }\r
164                 };\r
165 \r
166                 this.enable = function () {\r
167                         if (arguments.length === 0) {\r
168                                 // Called as: api.enable()\r
169                                 $menuEl.find('li.disabled').removeClass('disabled');\r
170                                 nodeToDisabledMenuItems = {};\r
171                         } else if (arguments.length === 1) {\r
172                                 // Called as: api.enable(['edit','remove'])\r
173                                 var items = arguments[0];\r
174                                 if (typeof items !== 'object') {\r
175                                         return;\r
176                                 }\r
177                                 \r
178                                 $menuEl.find('li > a').each(function () {\r
179                                         var hrefValue = $(this).attr('href');\r
180                                         var value = hrefValue.slice(hrefValue.indexOf("#") + 1, hrefValue.length)\r
181                                         if ($.inArray(value, items) > -1) {\r
182                                                 $(this).closest('li').removeClass('disabled');\r
183                                         }\r
184                                 });\r
185 \r
186                                 nodeToDisabledMenuItems = {};\r
187                         } else if (arguments.length === 2) {\r
188                                 // Called as: api.enable(nodeName, ['edit','remove'])\r
189                                 var nodeName = arguments[0];\r
190                                 var items = arguments[1];\r
191                                 if (items.length === 0) {\r
192                                         delete nodeToDisabledMenuItems[nodeName];\r
193                                 } else {\r
194                                         var disabledItems = nodeToDisabledMenuItems[nodeName];\r
195                                         for (var i = 0; i < items.length; i++) {\r
196                                                 var idx = disabledItems.indexOf(items[i]);\r
197                                                 if (idx > -1) {\r
198                                                         disabledItems.splice(idx, 1);\r
199                                                 }\r
200                                         }\r
201                                         if (disabledItems.length === 0) {\r
202                                                 delete nodeToDisabledMenuItems[nodeName];\r
203                                         } else {\r
204                                                 nodeToDisabledMenuItems[nodeName] = disabledItems;      \r
205                                         }\r
206                                 }\r
207                                 if (Object.keys(nodeToDisabledMenuItems).length === 0) {\r
208                                         $menuEl.find('li.disabled').removeClass('disabled');\r
209                                 }\r
210                         }\r
211                 };\r
212                 return this;\r
213         };\r
214 } (jQuery));\r