-
Notifications
You must be signed in to change notification settings - Fork 12
/
jstree-actions.js
194 lines (163 loc) · 6.1 KB
/
jstree-actions.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
(function (factory) {
"use strict";
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
}
else if(typeof module !== 'undefined' && module.exports) {
module.exports = factory(require('jquery'));
}
else {
factory(jQuery);
}
}(function ($, undefined) {
"use strict";
$.jstree.defaults.actions = $.noop;
$.jstree.plugins.actions = function (options, parent) {
this._actions = {};
/**
* @param node_id Can be a single node id or an array of node ids.
* @param action An object representing the action that should be added to <node>.
*
* The <node id> is the "id" key of each element of the "core.data" array.
* A special value "all" is allowed, in which case the action will be added to all nodes.
*
* The actions object can contain the following keys:
* id <- string An ID which identifies the action. The same ID can be shared across different nodes
* text <- string The action's text
* class <- string (a string containing all the classes you want to add to the action (space separated)
* title <- string The actions title for display of tooltip (optional)
* selector <- a selector that would specify where to insert the action. Note that this is a plain JavaScript selector and not a jQuery one.
* after <- bool (insert the action after (true) or before (false) the element matching the <selector> key
* event <- string The event on which the trigger will be called
* callback <- function that will be called when the action is clicked
*
* NOTES: Please keep in mind that:
* - the id's are strictly compared (===)
* - the selector has access to all children on nodes with leafs/children, so most probably you'd want to use :first or similar
*/
this.add_action = function (node_id, action) {
var self = this;
var node_ids = typeof node_id === 'object' ? node_id : [node_id];
var should_redraw_all = node_ids.indexOf("all") > -1;
for (var i = 0; i < node_ids.length; i++) {
var _node_id = node_ids[i];
var actions = self._actions[_node_id] = self._actions[_node_id] || [];
if (!self._has_action(_node_id, action.id)) {
actions.push(action);
if (!should_redraw_all) this.redraw_node(_node_id);
}
}
if (should_redraw_all) this.redraw(true);
};
/**
* @param node_id Can be a single node id or an array of node ids
* @param action_id The ID of the action to be removed
*
* The <node id> is the "id" key of each element of the "core.data" array.
* A special value "all" is allowed, in which case the action_id will be removed from all nodes.
*
* The action_id is the unique identifier for each action.
* A special value "all" is allowed, in which case all the actions of node_id will be removed.
*/
this.remove_action = function (node_id, action_id) {
var self = this;
var node_ids = typeof node_id === 'object' ? node_id :
node_id === "all" ? Object.keys(this._actions) : [node_id];
var should_redraw_all = node_ids.indexOf("all") > -1;
for (var i = 0; i < node_ids.length; i++) {
node_id = node_ids[i];
var actions = self._actions[node_id] || [];
var new_actions = [];
for (var j = 0; j < actions.length; j++) {
var action = actions[j];
if(action.id !== action_id && action_id !== "all") {
new_actions.push(action);
}
}
var ids = actions.map(function(x) { return x.id; });
var new_ids = new_actions.map(function(x) { return x.id; });
if (ids.length != new_ids.length || ids.filter(function(n) { return new_ids.indexOf(n) === -1; }).length) {
self._actions[node_id] = new_actions;
if (!should_redraw_all) this.redraw_node(node_id);
}
}
if (should_redraw_all) {
this.redraw(true);
}
};
this._create_action = function (node_id, action_id) {
var self = this;
var action = this._get_action(node_id, action_id);
if (action === null) return null;
var action_el = document.createElement("i");
action_el.className = action.class;
action_el.textContent = action.text;
if(action.title && action.title.length > 0){
action_el.title = action.title;
}
action_el.onclick = function(e) {
var node = self.get_node(action_el);
action.callback(node_id, node, action_id, action_el, e);
};
return {
"action": action,
"action_el": action_el
};
};
this._get_action = function (node_id, action_id) {
var actions = this._actions[node_id] || [];
var v = null;
for (var i = 0; i < actions.length; i++) {
var action = actions[i];
if (action.id === action_id) {
//TODO: fill empty fields with default values?
v = action;
}
}
return v;
};
this._set_action = function (node_id, obj, action) {
if (action === null) return;
var place = obj.querySelector(action.action.selector);
if (action.action.after) {
place.parentNode.insertBefore(action.action_el, place.nextSibling);
} else {
obj.insertBefore(action.action_el, place);
}
};
this._has_action = function (node_id, action_id) {
var found = false;
var actions = this._actions;
if (actions.hasOwnProperty(node_id)) {
for (var i = 0; i < actions[node_id].length; i++) {
if (actions[node_id][i].id === action_id) found = true;
}
}
if (this._actions.hasOwnProperty('all')) {
for (i = 0; i < actions['all'].length; i++) {
if (actions['all'][i].id === action_id) found = true;
}
}
return found;
};
this.redraw_node = function (obj, deep, callback, force_draw) {
var self = this;
var node_id = typeof obj === "object" ? obj.id : obj;
var el = parent.redraw_node.call(this, obj, deep, callback, force_draw);
if (el) {
//Check if we have any specific actions for this node
var actions = this._actions[node_id] || [];
for (var i = 0; i < actions.length; i++) {
var _action = self._create_action(node_id, actions[i].id);
self._set_action(node_id, el, _action);
}
actions = this._actions["all"] || [];
for (i = 0; i < actions.length; i++) {
_action = self._create_action("all", actions[i].id);
self._set_action(node_id, el, _action);
}
}
return el;
};
}
}));