2 * ============LICENSE_START==========================================
4 * ===================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ===================================================================
8 * Unless otherwise specified, all software contained herein is licensed
9 * under the Apache License, Version 2.0 (the "License");
10 * you may not use this software except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
21 * Unless otherwise specified, all documentation contained herein is licensed
22 * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
23 * you may not use this documentation except in compliance with the License.
24 * You may obtain a copy of the License at
26 * https://creativecommons.org/licenses/by/4.0/
28 * Unless required by applicable law or agreed to in writing, documentation
29 * distributed under the License is distributed on an "AS IS" BASIS,
30 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 * See the License for the specific language governing permissions and
32 * limitations under the License.
34 * ============LICENSE_END============================================
40 throw "Error jqTree is not loaded.";
43 $.fn.jqTreeContextMenu = function (menuElement, callbacks) {
46 // * Make sure the useContextMenu option is set in jqTree, either complain or set it automatically
47 // * Make menu fade in/out
52 // The jQuery object of the menu div.
53 var $menuEl = menuElement;
55 // This hash holds all menu items that should be disabled for a specific node.
56 var nodeToDisabledMenuItems = {};
61 // Disable system context menu from beeing displayed.
62 $el.bind("contextmenu", function (e) {
67 // Handle the contextmenu event sent from jqTree when user clicks right mouse button.
68 $el.bind('tree.contextmenu', function (event) {
69 var x = event.click_event.pageX;
70 var y = event.click_event.pageY;
73 var menuHeight = $menuEl.height();
74 var menuWidth = $menuEl.width();
75 var windowHeight = $(window).height();
76 var windowWidth = $(window).width();
78 if (menuHeight + y + yPadding > windowHeight) {
79 // Make sure the whole menu is rendered within the viewport.
82 if (menuWidth + x + xPadding > windowWidth) {
83 // Make sure the whole menu is rendered within the viewport.
87 // Handle disabling and enabling of menu items on specific nodes.
88 if (Object.keys(nodeToDisabledMenuItems).length > 0) {
89 if (event.node.name in nodeToDisabledMenuItems) {
90 var nodeName = event.node.name;
91 var items = nodeToDisabledMenuItems[nodeName];
92 if (items.length === 0) {
93 $menuEl.find('li').addClass('disabled');
94 $menuEl.find('li > a').unbind('click');
96 $menuEl.find('li > a').each(function () {
97 $(this).closest('li').removeClass('disabled');
98 var hrefValue = $(this).attr('href');
99 var value = hrefValue.slice(hrefValue.indexOf("#") + 1, hrefValue.length)
100 if ($.inArray(value, items) > -1) {
101 $(this).closest('li').addClass('disabled');
102 $(this).unbind('click');
107 $menuEl.find('li.disabled').removeClass('disabled');
111 // Must call show before we set the offset (offset can not be set on display: none elements).
114 $menuEl.offset({ left: x, top: y });
116 var dismissContextMenu = function () {
117 $(document).unbind('click.jqtreecontextmenu');
118 $el.unbind('tree.click.jqtreecontextmenu');
121 // Make it possible to dismiss context menu by clicking somewhere in the document.
122 $(document).bind('click.jqtreecontextmenu', function () {
123 dismissContextMenu();
126 // Dismiss context menu if another node in the tree is clicked.
127 $el.bind('tree.click.jqtreecontextmenu', function (e) {
128 dismissContextMenu();
131 // Make selection follow the node that was right clicked on.
132 var selectedNode = $el.tree('getSelectedNode');
133 if (selectedNode !== event.node) {
134 $el.tree('selectNode', event.node);
137 // Handle click on menu items, if it's not disabled.
138 var menuItems = $menuEl.find('li:not(.disabled) a');
139 if (menuItems.length !== 0) {
140 menuItems.unbind('click');
141 menuItems.click(function (e) {
142 e.stopImmediatePropagation();
143 dismissContextMenu();
144 var hrefAnchor = e.currentTarget.attributes.href.nodeValue;
145 var funcKey = hrefAnchor.slice(hrefAnchor.indexOf("#") + 1, hrefAnchor.length)
146 var callbackFn = callbacks[funcKey];
148 callbackFn(event.node);
155 this.disable = function () {
156 if (arguments.length === 0) {
157 // Called as: api.disable()
158 $menuEl.find('li:not(.disabled)').addClass('disabled');
159 $menuEl.find('li a').unbind('click');
160 nodeToDisabledMenuItems = {};
161 } else if (arguments.length === 1) {
162 // Called as: api.disable(['edit','remove'])
163 var items = arguments[0];
164 if (typeof items !== 'object') {
167 $menuEl.find('li > a').each(function () {
168 var hrefValue = $(this).attr('href');
169 var value = hrefValue.slice(hrefValue.indexOf("#") + 1, hrefValue.length)
170 if ($.inArray(value, items) > -1) {
171 $(this).closest('li').addClass('disabled');
172 $(this).unbind('click');
175 nodeToDisabledMenuItems = {};
176 } else if (arguments.length === 2) {
177 // Called as: api.disable(nodeName, ['edit','remove'])
178 var nodeName = arguments[0];
179 var items = arguments[1];
180 nodeToDisabledMenuItems[nodeName] = items;
184 this.enable = function () {
185 if (arguments.length === 0) {
186 // Called as: api.enable()
187 $menuEl.find('li.disabled').removeClass('disabled');
188 nodeToDisabledMenuItems = {};
189 } else if (arguments.length === 1) {
190 // Called as: api.enable(['edit','remove'])
191 var items = arguments[0];
192 if (typeof items !== 'object') {
196 $menuEl.find('li > a').each(function () {
197 var hrefValue = $(this).attr('href');
198 var value = hrefValue.slice(hrefValue.indexOf("#") + 1, hrefValue.length)
199 if ($.inArray(value, items) > -1) {
200 $(this).closest('li').removeClass('disabled');
204 nodeToDisabledMenuItems = {};
205 } else if (arguments.length === 2) {
206 // Called as: api.enable(nodeName, ['edit','remove'])
207 var nodeName = arguments[0];
208 var items = arguments[1];
209 if (items.length === 0) {
210 delete nodeToDisabledMenuItems[nodeName];
212 var disabledItems = nodeToDisabledMenuItems[nodeName];
213 for (var i = 0; i < items.length; i++) {
214 var idx = disabledItems.indexOf(items[i]);
216 disabledItems.splice(idx, 1);
219 if (disabledItems.length === 0) {
220 delete nodeToDisabledMenuItems[nodeName];
222 nodeToDisabledMenuItems[nodeName] = disabledItems;
225 if (Object.keys(nodeToDisabledMenuItems).length === 0) {
226 $menuEl.find('li.disabled').removeClass('disabled');