sequenceserver 2.0.0.rc8 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sequenceserver might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/bin/sequenceserver +22 -30
- data/lib/sequenceserver/api_errors.rb +5 -1
- data/lib/sequenceserver/blast/constants.rb +1 -1
- data/lib/sequenceserver/blast/hit.rb +5 -16
- data/lib/sequenceserver/blast/job.rb +9 -18
- data/lib/sequenceserver/blast/report.rb +5 -3
- data/lib/sequenceserver/config.rb +4 -1
- data/lib/sequenceserver/database.rb +69 -9
- data/lib/sequenceserver/job.rb +1 -1
- data/lib/sequenceserver/makeblastdb.rb +40 -45
- data/lib/sequenceserver/routes.rb +4 -0
- data/lib/sequenceserver/version.rb +1 -1
- data/lib/sequenceserver.rb +15 -11
- data/public/config.js +143 -142
- data/public/css/fonts.css +23 -22
- data/public/css/grapher.css +598 -594
- data/public/css/sequenceserver.css +86 -24
- data/public/css/sequenceserver.min.css +2 -2
- data/public/js/alignment_exporter.js +14 -14
- data/public/js/databases_tree.js +215 -0
- data/public/js/download_fasta.js +1 -1
- data/public/js/hit.js +6 -2
- data/public/js/hits_overview.js +1 -1
- data/public/js/length_distribution.js +5 -5
- data/public/js/query.js +4 -7
- data/public/js/report.js +12 -24
- data/public/js/search.js +21 -2
- data/public/js/sidebar.js +4 -4
- data/public/js/svgExporter.js +12 -12
- data/public/js/visualisation_helpers.js +4 -5
- data/public/sequenceserver-report.min.js +11 -11
- data/public/sequenceserver-search.min.js +15 -11
- data/public/vendor/github/vakata/jstree@3.3.8/LICENSE-MIT +22 -0
- data/public/vendor/github/vakata/jstree@3.3.8/README.md +663 -0
- data/public/vendor/github/vakata/jstree@3.3.8/bower.json +33 -0
- data/public/vendor/github/vakata/jstree@3.3.8/component.json +28 -0
- data/public/vendor/github/vakata/jstree@3.3.8/composer.json +46 -0
- data/public/vendor/github/vakata/jstree@3.3.8/demo/README.md +2 -0
- data/public/vendor/github/vakata/jstree@3.3.8/demo/basic/index.html +146 -0
- data/public/vendor/github/vakata/jstree@3.3.8/demo/basic/root.json +1 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/jstree.js +8612 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/jstree.min.js +6 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default/32px.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default/40px.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default/style.css +1102 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default/style.min.css +1 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default/throbber.gif +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default-dark/32px.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default-dark/40px.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default-dark/style.css +1146 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default-dark/style.min.css +1 -0
- data/public/vendor/github/vakata/jstree@3.3.8/dist/themes/default-dark/throbber.gif +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/gruntfile.js +242 -0
- data/public/vendor/github/vakata/jstree@3.3.8/jstree.jquery.json +28 -0
- data/public/vendor/github/vakata/jstree@3.3.8/package.json +58 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/intro.js +14 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.changed.js +69 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.checkbox.js +976 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.conditionalselect.js +38 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.contextmenu.js +661 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.dnd.js +669 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.js +4931 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.massload.js +137 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.search.js +421 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.sort.js +74 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.state.js +138 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.types.js +372 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.unique.js +164 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/jstree.wholerow.js +122 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/misc.js +656 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/outro.js +1 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/sample.js +93 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/base.less +93 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default/32px.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default/40px.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default/style.css +1102 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default/style.less +22 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default/throbber.gif +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default-dark/32px.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default-dark/40px.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default-dark/style.css +1146 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default-dark/style.less +50 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/default-dark/throbber.gif +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/main.less +77 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/mixins.less +104 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/themes/responsive.less +67 -0
- data/public/vendor/github/vakata/jstree@3.3.8/src/vakata-jstree.js +38 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/unit/index.html +16 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/unit/libs/qunit.css +244 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/unit/libs/qunit.js +2212 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/unit/test.js +11 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/visual/desktop/index.html +44 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/visual/mobile/index.html +42 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/visual/screenshots/desktop/desktop.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/visual/screenshots/desktop/home.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/visual/screenshots/mobile/home.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8/test/visual/screenshots/mobile/mobile.png +0 -0
- data/public/vendor/github/vakata/jstree@3.3.8.js +3 -0
- data/public/vendor/system-csp-production.js +3 -3
- data/public/vendor/system-csp-production.js.map +1 -1
- data/public/vendor/system-csp-production.src.js +146 -140
- data/public/vendor/system-polyfills.js.map +1 -1
- data/public/vendor/system-polyfills.src.js +1 -0
- data/public/vendor/system.js +3 -3
- data/public/vendor/system.js.map +1 -1
- data/public/vendor/system.src.js +4771 -2383
- data/views/_options.erb +21 -0
- data/views/layout.erb +17 -18
- metadata +102 -43
- data/bin/chromedriver +0 -0
- data/bin/geckodriver +0 -0
- data/public/shims/form-core.js +0 -3
- data/public/shims/form-validation.js +0 -3
- data/public/shims/plugins/jquery.ui.position.js +0 -13
- data/public/shims/styles/shim.css +0 -1
@@ -0,0 +1,976 @@
|
|
1
|
+
/**
|
2
|
+
* ### Checkbox plugin
|
3
|
+
*
|
4
|
+
* This plugin renders checkbox icons in front of each node, making multiple selection much easier.
|
5
|
+
* It also supports tri-state behavior, meaning that if a node has a few of its children checked it will be rendered as undetermined, and state will be propagated up.
|
6
|
+
*/
|
7
|
+
/*globals jQuery, define, exports, require, document */
|
8
|
+
(function (factory) {
|
9
|
+
"use strict";
|
10
|
+
if (typeof define === 'function' && define.amd) {
|
11
|
+
define('jstree.checkbox', ['jquery','jstree'], factory);
|
12
|
+
}
|
13
|
+
else if(typeof exports === 'object') {
|
14
|
+
factory(require('jquery'), require('jstree'));
|
15
|
+
}
|
16
|
+
else {
|
17
|
+
factory(jQuery, jQuery.jstree);
|
18
|
+
}
|
19
|
+
}(function ($, jstree, undefined) {
|
20
|
+
"use strict";
|
21
|
+
|
22
|
+
if($.jstree.plugins.checkbox) { return; }
|
23
|
+
|
24
|
+
var _i = document.createElement('I');
|
25
|
+
_i.className = 'jstree-icon jstree-checkbox';
|
26
|
+
_i.setAttribute('role', 'presentation');
|
27
|
+
/**
|
28
|
+
* stores all defaults for the checkbox plugin
|
29
|
+
* @name $.jstree.defaults.checkbox
|
30
|
+
* @plugin checkbox
|
31
|
+
*/
|
32
|
+
$.jstree.defaults.checkbox = {
|
33
|
+
/**
|
34
|
+
* a boolean indicating if checkboxes should be visible (can be changed at a later time using `show_checkboxes()` and `hide_checkboxes`). Defaults to `true`.
|
35
|
+
* @name $.jstree.defaults.checkbox.visible
|
36
|
+
* @plugin checkbox
|
37
|
+
*/
|
38
|
+
visible : true,
|
39
|
+
/**
|
40
|
+
* a boolean indicating if checkboxes should cascade down and have an undetermined state. Defaults to `true`.
|
41
|
+
* @name $.jstree.defaults.checkbox.three_state
|
42
|
+
* @plugin checkbox
|
43
|
+
*/
|
44
|
+
three_state : true,
|
45
|
+
/**
|
46
|
+
* a boolean indicating if clicking anywhere on the node should act as clicking on the checkbox. Defaults to `true`.
|
47
|
+
* @name $.jstree.defaults.checkbox.whole_node
|
48
|
+
* @plugin checkbox
|
49
|
+
*/
|
50
|
+
whole_node : true,
|
51
|
+
/**
|
52
|
+
* a boolean indicating if the selected style of a node should be kept, or removed. Defaults to `true`.
|
53
|
+
* @name $.jstree.defaults.checkbox.keep_selected_style
|
54
|
+
* @plugin checkbox
|
55
|
+
*/
|
56
|
+
keep_selected_style : true,
|
57
|
+
/**
|
58
|
+
* This setting controls how cascading and undetermined nodes are applied.
|
59
|
+
* If 'up' is in the string - cascading up is enabled, if 'down' is in the string - cascading down is enabled, if 'undetermined' is in the string - undetermined nodes will be used.
|
60
|
+
* If `three_state` is set to `true` this setting is automatically set to 'up+down+undetermined'. Defaults to ''.
|
61
|
+
* @name $.jstree.defaults.checkbox.cascade
|
62
|
+
* @plugin checkbox
|
63
|
+
*/
|
64
|
+
cascade : '',
|
65
|
+
/**
|
66
|
+
* This setting controls if checkbox are bound to the general tree selection or to an internal array maintained by the checkbox plugin. Defaults to `true`, only set to `false` if you know exactly what you are doing.
|
67
|
+
* @name $.jstree.defaults.checkbox.tie_selection
|
68
|
+
* @plugin checkbox
|
69
|
+
*/
|
70
|
+
tie_selection : true,
|
71
|
+
|
72
|
+
/**
|
73
|
+
* This setting controls if cascading down affects disabled checkboxes
|
74
|
+
* @name $.jstree.defaults.checkbox.cascade_to_disabled
|
75
|
+
* @plugin checkbox
|
76
|
+
*/
|
77
|
+
cascade_to_disabled : true,
|
78
|
+
|
79
|
+
/**
|
80
|
+
* This setting controls if cascading down affects hidden checkboxes
|
81
|
+
* @name $.jstree.defaults.checkbox.cascade_to_hidden
|
82
|
+
* @plugin checkbox
|
83
|
+
*/
|
84
|
+
cascade_to_hidden : true
|
85
|
+
};
|
86
|
+
$.jstree.plugins.checkbox = function (options, parent) {
|
87
|
+
this.bind = function () {
|
88
|
+
parent.bind.call(this);
|
89
|
+
this._data.checkbox.uto = false;
|
90
|
+
this._data.checkbox.selected = [];
|
91
|
+
if(this.settings.checkbox.three_state) {
|
92
|
+
this.settings.checkbox.cascade = 'up+down+undetermined';
|
93
|
+
}
|
94
|
+
this.element
|
95
|
+
.on("init.jstree", $.proxy(function () {
|
96
|
+
this._data.checkbox.visible = this.settings.checkbox.visible;
|
97
|
+
if(!this.settings.checkbox.keep_selected_style) {
|
98
|
+
this.element.addClass('jstree-checkbox-no-clicked');
|
99
|
+
}
|
100
|
+
if(this.settings.checkbox.tie_selection) {
|
101
|
+
this.element.addClass('jstree-checkbox-selection');
|
102
|
+
}
|
103
|
+
}, this))
|
104
|
+
.on("loading.jstree", $.proxy(function () {
|
105
|
+
this[ this._data.checkbox.visible ? 'show_checkboxes' : 'hide_checkboxes' ]();
|
106
|
+
}, this));
|
107
|
+
if(this.settings.checkbox.cascade.indexOf('undetermined') !== -1) {
|
108
|
+
this.element
|
109
|
+
.on('changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree', $.proxy(function () {
|
110
|
+
// only if undetermined is in setting
|
111
|
+
if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); }
|
112
|
+
this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50);
|
113
|
+
}, this));
|
114
|
+
}
|
115
|
+
if(!this.settings.checkbox.tie_selection) {
|
116
|
+
this.element
|
117
|
+
.on('model.jstree', $.proxy(function (e, data) {
|
118
|
+
var m = this._model.data,
|
119
|
+
p = m[data.parent],
|
120
|
+
dpc = data.nodes,
|
121
|
+
i, j;
|
122
|
+
for(i = 0, j = dpc.length; i < j; i++) {
|
123
|
+
m[dpc[i]].state.checked = m[dpc[i]].state.checked || (m[dpc[i]].original && m[dpc[i]].original.state && m[dpc[i]].original.state.checked);
|
124
|
+
if(m[dpc[i]].state.checked) {
|
125
|
+
this._data.checkbox.selected.push(dpc[i]);
|
126
|
+
}
|
127
|
+
}
|
128
|
+
}, this));
|
129
|
+
}
|
130
|
+
if(this.settings.checkbox.cascade.indexOf('up') !== -1 || this.settings.checkbox.cascade.indexOf('down') !== -1) {
|
131
|
+
this.element
|
132
|
+
.on('model.jstree', $.proxy(function (e, data) {
|
133
|
+
var m = this._model.data,
|
134
|
+
p = m[data.parent],
|
135
|
+
dpc = data.nodes,
|
136
|
+
chd = [],
|
137
|
+
c, i, j, k, l, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection;
|
138
|
+
|
139
|
+
if(s.indexOf('down') !== -1) {
|
140
|
+
// apply down
|
141
|
+
if(p.state[ t ? 'selected' : 'checked' ]) {
|
142
|
+
for(i = 0, j = dpc.length; i < j; i++) {
|
143
|
+
m[dpc[i]].state[ t ? 'selected' : 'checked' ] = true;
|
144
|
+
}
|
145
|
+
|
146
|
+
this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(dpc);
|
147
|
+
}
|
148
|
+
else {
|
149
|
+
for(i = 0, j = dpc.length; i < j; i++) {
|
150
|
+
if(m[dpc[i]].state[ t ? 'selected' : 'checked' ]) {
|
151
|
+
for(k = 0, l = m[dpc[i]].children_d.length; k < l; k++) {
|
152
|
+
m[m[dpc[i]].children_d[k]].state[ t ? 'selected' : 'checked' ] = true;
|
153
|
+
}
|
154
|
+
this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(m[dpc[i]].children_d);
|
155
|
+
}
|
156
|
+
}
|
157
|
+
}
|
158
|
+
}
|
159
|
+
|
160
|
+
if(s.indexOf('up') !== -1) {
|
161
|
+
// apply up
|
162
|
+
for(i = 0, j = p.children_d.length; i < j; i++) {
|
163
|
+
if(!m[p.children_d[i]].children.length) {
|
164
|
+
chd.push(m[p.children_d[i]].parent);
|
165
|
+
}
|
166
|
+
}
|
167
|
+
chd = $.vakata.array_unique(chd);
|
168
|
+
for(k = 0, l = chd.length; k < l; k++) {
|
169
|
+
p = m[chd[k]];
|
170
|
+
while(p && p.id !== $.jstree.root) {
|
171
|
+
c = 0;
|
172
|
+
for(i = 0, j = p.children.length; i < j; i++) {
|
173
|
+
c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
|
174
|
+
}
|
175
|
+
if(c === j) {
|
176
|
+
p.state[ t ? 'selected' : 'checked' ] = true;
|
177
|
+
this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);
|
178
|
+
tmp = this.get_node(p, true);
|
179
|
+
if(tmp && tmp.length) {
|
180
|
+
tmp.attr('aria-selected', true).children('.jstree-anchor').addClass( t ? 'jstree-clicked' : 'jstree-checked');
|
181
|
+
}
|
182
|
+
}
|
183
|
+
else {
|
184
|
+
break;
|
185
|
+
}
|
186
|
+
p = this.get_node(p.parent);
|
187
|
+
}
|
188
|
+
}
|
189
|
+
}
|
190
|
+
|
191
|
+
this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected);
|
192
|
+
}, this))
|
193
|
+
.on(this.settings.checkbox.tie_selection ? 'select_node.jstree' : 'check_node.jstree', $.proxy(function (e, data) {
|
194
|
+
var self = this,
|
195
|
+
obj = data.node,
|
196
|
+
m = this._model.data,
|
197
|
+
par = this.get_node(obj.parent),
|
198
|
+
i, j, c, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection,
|
199
|
+
sel = {}, cur = this._data[ t ? 'core' : 'checkbox' ].selected;
|
200
|
+
|
201
|
+
for (i = 0, j = cur.length; i < j; i++) {
|
202
|
+
sel[cur[i]] = true;
|
203
|
+
}
|
204
|
+
|
205
|
+
// apply down
|
206
|
+
if(s.indexOf('down') !== -1) {
|
207
|
+
//this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected.concat(obj.children_d));
|
208
|
+
var selectedIds = this._cascade_new_checked_state(obj.id, true);
|
209
|
+
var temp = obj.children_d.concat(obj.id);
|
210
|
+
for (i = 0, j = temp.length; i < j; i++) {
|
211
|
+
if (selectedIds.indexOf(temp[i]) > -1) {
|
212
|
+
sel[temp[i]] = true;
|
213
|
+
}
|
214
|
+
else {
|
215
|
+
delete sel[temp[i]];
|
216
|
+
}
|
217
|
+
}
|
218
|
+
}
|
219
|
+
|
220
|
+
// apply up
|
221
|
+
if(s.indexOf('up') !== -1) {
|
222
|
+
while(par && par.id !== $.jstree.root) {
|
223
|
+
c = 0;
|
224
|
+
for(i = 0, j = par.children.length; i < j; i++) {
|
225
|
+
c += m[par.children[i]].state[ t ? 'selected' : 'checked' ];
|
226
|
+
}
|
227
|
+
if(c === j) {
|
228
|
+
par.state[ t ? 'selected' : 'checked' ] = true;
|
229
|
+
sel[par.id] = true;
|
230
|
+
//this._data[ t ? 'core' : 'checkbox' ].selected.push(par.id);
|
231
|
+
tmp = this.get_node(par, true);
|
232
|
+
if(tmp && tmp.length) {
|
233
|
+
tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
|
234
|
+
}
|
235
|
+
}
|
236
|
+
else {
|
237
|
+
break;
|
238
|
+
}
|
239
|
+
par = this.get_node(par.parent);
|
240
|
+
}
|
241
|
+
}
|
242
|
+
|
243
|
+
cur = [];
|
244
|
+
for (i in sel) {
|
245
|
+
if (sel.hasOwnProperty(i)) {
|
246
|
+
cur.push(i);
|
247
|
+
}
|
248
|
+
}
|
249
|
+
this._data[ t ? 'core' : 'checkbox' ].selected = cur;
|
250
|
+
}, this))
|
251
|
+
.on(this.settings.checkbox.tie_selection ? 'deselect_all.jstree' : 'uncheck_all.jstree', $.proxy(function (e, data) {
|
252
|
+
var obj = this.get_node($.jstree.root),
|
253
|
+
m = this._model.data,
|
254
|
+
i, j, tmp;
|
255
|
+
for(i = 0, j = obj.children_d.length; i < j; i++) {
|
256
|
+
tmp = m[obj.children_d[i]];
|
257
|
+
if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) {
|
258
|
+
tmp.original.state.undetermined = false;
|
259
|
+
}
|
260
|
+
}
|
261
|
+
}, this))
|
262
|
+
.on(this.settings.checkbox.tie_selection ? 'deselect_node.jstree' : 'uncheck_node.jstree', $.proxy(function (e, data) {
|
263
|
+
var self = this,
|
264
|
+
obj = data.node,
|
265
|
+
dom = this.get_node(obj, true),
|
266
|
+
i, j, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection,
|
267
|
+
cur = this._data[ t ? 'core' : 'checkbox' ].selected, sel = {},
|
268
|
+
stillSelectedIds = [],
|
269
|
+
allIds = obj.children_d.concat(obj.id);
|
270
|
+
|
271
|
+
// apply down
|
272
|
+
if(s.indexOf('down') !== -1) {
|
273
|
+
var selectedIds = this._cascade_new_checked_state(obj.id, false);
|
274
|
+
|
275
|
+
cur = $.vakata.array_filter(cur, function(id) {
|
276
|
+
return allIds.indexOf(id) === -1 || selectedIds.indexOf(id) > -1;
|
277
|
+
});
|
278
|
+
}
|
279
|
+
|
280
|
+
// only apply up if cascade up is enabled and if this node is not selected
|
281
|
+
// (if all child nodes are disabled and cascade_to_disabled === false then this node will till be selected).
|
282
|
+
if(s.indexOf('up') !== -1 && cur.indexOf(obj.id) === -1) {
|
283
|
+
for(i = 0, j = obj.parents.length; i < j; i++) {
|
284
|
+
tmp = this._model.data[obj.parents[i]];
|
285
|
+
tmp.state[ t ? 'selected' : 'checked' ] = false;
|
286
|
+
if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) {
|
287
|
+
tmp.original.state.undetermined = false;
|
288
|
+
}
|
289
|
+
tmp = this.get_node(obj.parents[i], true);
|
290
|
+
if(tmp && tmp.length) {
|
291
|
+
tmp.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked');
|
292
|
+
}
|
293
|
+
}
|
294
|
+
|
295
|
+
cur = $.vakata.array_filter(cur, function(id) {
|
296
|
+
return obj.parents.indexOf(id) === -1;
|
297
|
+
});
|
298
|
+
}
|
299
|
+
|
300
|
+
this._data[ t ? 'core' : 'checkbox' ].selected = cur;
|
301
|
+
}, this));
|
302
|
+
}
|
303
|
+
if(this.settings.checkbox.cascade.indexOf('up') !== -1) {
|
304
|
+
this.element
|
305
|
+
.on('delete_node.jstree', $.proxy(function (e, data) {
|
306
|
+
// apply up (whole handler)
|
307
|
+
var p = this.get_node(data.parent),
|
308
|
+
m = this._model.data,
|
309
|
+
i, j, c, tmp, t = this.settings.checkbox.tie_selection;
|
310
|
+
while(p && p.id !== $.jstree.root && !p.state[ t ? 'selected' : 'checked' ]) {
|
311
|
+
c = 0;
|
312
|
+
for(i = 0, j = p.children.length; i < j; i++) {
|
313
|
+
c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
|
314
|
+
}
|
315
|
+
if(j > 0 && c === j) {
|
316
|
+
p.state[ t ? 'selected' : 'checked' ] = true;
|
317
|
+
this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);
|
318
|
+
tmp = this.get_node(p, true);
|
319
|
+
if(tmp && tmp.length) {
|
320
|
+
tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
|
321
|
+
}
|
322
|
+
}
|
323
|
+
else {
|
324
|
+
break;
|
325
|
+
}
|
326
|
+
p = this.get_node(p.parent);
|
327
|
+
}
|
328
|
+
}, this))
|
329
|
+
.on('move_node.jstree', $.proxy(function (e, data) {
|
330
|
+
// apply up (whole handler)
|
331
|
+
var is_multi = data.is_multi,
|
332
|
+
old_par = data.old_parent,
|
333
|
+
new_par = this.get_node(data.parent),
|
334
|
+
m = this._model.data,
|
335
|
+
p, c, i, j, tmp, t = this.settings.checkbox.tie_selection;
|
336
|
+
if(!is_multi) {
|
337
|
+
p = this.get_node(old_par);
|
338
|
+
while(p && p.id !== $.jstree.root && !p.state[ t ? 'selected' : 'checked' ]) {
|
339
|
+
c = 0;
|
340
|
+
for(i = 0, j = p.children.length; i < j; i++) {
|
341
|
+
c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
|
342
|
+
}
|
343
|
+
if(j > 0 && c === j) {
|
344
|
+
p.state[ t ? 'selected' : 'checked' ] = true;
|
345
|
+
this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);
|
346
|
+
tmp = this.get_node(p, true);
|
347
|
+
if(tmp && tmp.length) {
|
348
|
+
tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
|
349
|
+
}
|
350
|
+
}
|
351
|
+
else {
|
352
|
+
break;
|
353
|
+
}
|
354
|
+
p = this.get_node(p.parent);
|
355
|
+
}
|
356
|
+
}
|
357
|
+
p = new_par;
|
358
|
+
while(p && p.id !== $.jstree.root) {
|
359
|
+
c = 0;
|
360
|
+
for(i = 0, j = p.children.length; i < j; i++) {
|
361
|
+
c += m[p.children[i]].state[ t ? 'selected' : 'checked' ];
|
362
|
+
}
|
363
|
+
if(c === j) {
|
364
|
+
if(!p.state[ t ? 'selected' : 'checked' ]) {
|
365
|
+
p.state[ t ? 'selected' : 'checked' ] = true;
|
366
|
+
this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id);
|
367
|
+
tmp = this.get_node(p, true);
|
368
|
+
if(tmp && tmp.length) {
|
369
|
+
tmp.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
|
370
|
+
}
|
371
|
+
}
|
372
|
+
}
|
373
|
+
else {
|
374
|
+
if(p.state[ t ? 'selected' : 'checked' ]) {
|
375
|
+
p.state[ t ? 'selected' : 'checked' ] = false;
|
376
|
+
this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_remove_item(this._data[ t ? 'core' : 'checkbox' ].selected, p.id);
|
377
|
+
tmp = this.get_node(p, true);
|
378
|
+
if(tmp && tmp.length) {
|
379
|
+
tmp.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked');
|
380
|
+
}
|
381
|
+
}
|
382
|
+
else {
|
383
|
+
break;
|
384
|
+
}
|
385
|
+
}
|
386
|
+
p = this.get_node(p.parent);
|
387
|
+
}
|
388
|
+
}, this));
|
389
|
+
}
|
390
|
+
};
|
391
|
+
/**
|
392
|
+
* get an array of all nodes whose state is "undetermined"
|
393
|
+
* @name get_undetermined([full])
|
394
|
+
* @param {boolean} full: if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
|
395
|
+
* @return {Array}
|
396
|
+
* @plugin checkbox
|
397
|
+
*/
|
398
|
+
this.get_undetermined = function (full) {
|
399
|
+
if (this.settings.checkbox.cascade.indexOf('undetermined') === -1) {
|
400
|
+
return [];
|
401
|
+
}
|
402
|
+
var i, j, k, l, o = {}, m = this._model.data, t = this.settings.checkbox.tie_selection, s = this._data[ t ? 'core' : 'checkbox' ].selected, p = [], tt = this, r = [];
|
403
|
+
for(i = 0, j = s.length; i < j; i++) {
|
404
|
+
if(m[s[i]] && m[s[i]].parents) {
|
405
|
+
for(k = 0, l = m[s[i]].parents.length; k < l; k++) {
|
406
|
+
if(o[m[s[i]].parents[k]] !== undefined) {
|
407
|
+
break;
|
408
|
+
}
|
409
|
+
if(m[s[i]].parents[k] !== $.jstree.root) {
|
410
|
+
o[m[s[i]].parents[k]] = true;
|
411
|
+
p.push(m[s[i]].parents[k]);
|
412
|
+
}
|
413
|
+
}
|
414
|
+
}
|
415
|
+
}
|
416
|
+
// attempt for server side undetermined state
|
417
|
+
this.element.find('.jstree-closed').not(':has(.jstree-children)')
|
418
|
+
.each(function () {
|
419
|
+
var tmp = tt.get_node(this), tmp2;
|
420
|
+
|
421
|
+
if(!tmp) { return; }
|
422
|
+
|
423
|
+
if(!tmp.state.loaded) {
|
424
|
+
if(tmp.original && tmp.original.state && tmp.original.state.undetermined && tmp.original.state.undetermined === true) {
|
425
|
+
if(o[tmp.id] === undefined && tmp.id !== $.jstree.root) {
|
426
|
+
o[tmp.id] = true;
|
427
|
+
p.push(tmp.id);
|
428
|
+
}
|
429
|
+
for(k = 0, l = tmp.parents.length; k < l; k++) {
|
430
|
+
if(o[tmp.parents[k]] === undefined && tmp.parents[k] !== $.jstree.root) {
|
431
|
+
o[tmp.parents[k]] = true;
|
432
|
+
p.push(tmp.parents[k]);
|
433
|
+
}
|
434
|
+
}
|
435
|
+
}
|
436
|
+
}
|
437
|
+
else {
|
438
|
+
for(i = 0, j = tmp.children_d.length; i < j; i++) {
|
439
|
+
tmp2 = m[tmp.children_d[i]];
|
440
|
+
if(!tmp2.state.loaded && tmp2.original && tmp2.original.state && tmp2.original.state.undetermined && tmp2.original.state.undetermined === true) {
|
441
|
+
if(o[tmp2.id] === undefined && tmp2.id !== $.jstree.root) {
|
442
|
+
o[tmp2.id] = true;
|
443
|
+
p.push(tmp2.id);
|
444
|
+
}
|
445
|
+
for(k = 0, l = tmp2.parents.length; k < l; k++) {
|
446
|
+
if(o[tmp2.parents[k]] === undefined && tmp2.parents[k] !== $.jstree.root) {
|
447
|
+
o[tmp2.parents[k]] = true;
|
448
|
+
p.push(tmp2.parents[k]);
|
449
|
+
}
|
450
|
+
}
|
451
|
+
}
|
452
|
+
}
|
453
|
+
}
|
454
|
+
});
|
455
|
+
for (i = 0, j = p.length; i < j; i++) {
|
456
|
+
if(!m[p[i]].state[ t ? 'selected' : 'checked' ]) {
|
457
|
+
r.push(full ? m[p[i]] : p[i]);
|
458
|
+
}
|
459
|
+
}
|
460
|
+
return r;
|
461
|
+
};
|
462
|
+
/**
|
463
|
+
* set the undetermined state where and if necessary. Used internally.
|
464
|
+
* @private
|
465
|
+
* @name _undetermined()
|
466
|
+
* @plugin checkbox
|
467
|
+
*/
|
468
|
+
this._undetermined = function () {
|
469
|
+
if(this.element === null) { return; }
|
470
|
+
var p = this.get_undetermined(false), i, j, s;
|
471
|
+
|
472
|
+
this.element.find('.jstree-undetermined').removeClass('jstree-undetermined');
|
473
|
+
for (i = 0, j = p.length; i < j; i++) {
|
474
|
+
s = this.get_node(p[i], true);
|
475
|
+
if(s && s.length) {
|
476
|
+
s.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-undetermined');
|
477
|
+
}
|
478
|
+
}
|
479
|
+
};
|
480
|
+
this.redraw_node = function(obj, deep, is_callback, force_render) {
|
481
|
+
obj = parent.redraw_node.apply(this, arguments);
|
482
|
+
if(obj) {
|
483
|
+
var i, j, tmp = null, icon = null;
|
484
|
+
for(i = 0, j = obj.childNodes.length; i < j; i++) {
|
485
|
+
if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) {
|
486
|
+
tmp = obj.childNodes[i];
|
487
|
+
break;
|
488
|
+
}
|
489
|
+
}
|
490
|
+
if(tmp) {
|
491
|
+
if(!this.settings.checkbox.tie_selection && this._model.data[obj.id].state.checked) { tmp.className += ' jstree-checked'; }
|
492
|
+
icon = _i.cloneNode(false);
|
493
|
+
if(this._model.data[obj.id].state.checkbox_disabled) { icon.className += ' jstree-checkbox-disabled'; }
|
494
|
+
tmp.insertBefore(icon, tmp.childNodes[0]);
|
495
|
+
}
|
496
|
+
}
|
497
|
+
if(!is_callback && this.settings.checkbox.cascade.indexOf('undetermined') !== -1) {
|
498
|
+
if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); }
|
499
|
+
this._data.checkbox.uto = setTimeout($.proxy(this._undetermined, this), 50);
|
500
|
+
}
|
501
|
+
return obj;
|
502
|
+
};
|
503
|
+
/**
|
504
|
+
* show the node checkbox icons
|
505
|
+
* @name show_checkboxes()
|
506
|
+
* @plugin checkbox
|
507
|
+
*/
|
508
|
+
this.show_checkboxes = function () { this._data.core.themes.checkboxes = true; this.get_container_ul().removeClass("jstree-no-checkboxes"); };
|
509
|
+
/**
|
510
|
+
* hide the node checkbox icons
|
511
|
+
* @name hide_checkboxes()
|
512
|
+
* @plugin checkbox
|
513
|
+
*/
|
514
|
+
this.hide_checkboxes = function () { this._data.core.themes.checkboxes = false; this.get_container_ul().addClass("jstree-no-checkboxes"); };
|
515
|
+
/**
|
516
|
+
* toggle the node icons
|
517
|
+
* @name toggle_checkboxes()
|
518
|
+
* @plugin checkbox
|
519
|
+
*/
|
520
|
+
this.toggle_checkboxes = function () { if(this._data.core.themes.checkboxes) { this.hide_checkboxes(); } else { this.show_checkboxes(); } };
|
521
|
+
/**
|
522
|
+
* checks if a node is in an undetermined state
|
523
|
+
* @name is_undetermined(obj)
|
524
|
+
* @param {mixed} obj
|
525
|
+
* @return {Boolean}
|
526
|
+
*/
|
527
|
+
this.is_undetermined = function (obj) {
|
528
|
+
obj = this.get_node(obj);
|
529
|
+
var s = this.settings.checkbox.cascade, i, j, t = this.settings.checkbox.tie_selection, d = this._data[ t ? 'core' : 'checkbox' ].selected, m = this._model.data;
|
530
|
+
if(!obj || obj.state[ t ? 'selected' : 'checked' ] === true || s.indexOf('undetermined') === -1 || (s.indexOf('down') === -1 && s.indexOf('up') === -1)) {
|
531
|
+
return false;
|
532
|
+
}
|
533
|
+
if(!obj.state.loaded && obj.original.state.undetermined === true) {
|
534
|
+
return true;
|
535
|
+
}
|
536
|
+
for(i = 0, j = obj.children_d.length; i < j; i++) {
|
537
|
+
if($.inArray(obj.children_d[i], d) !== -1 || (!m[obj.children_d[i]].state.loaded && m[obj.children_d[i]].original.state.undetermined)) {
|
538
|
+
return true;
|
539
|
+
}
|
540
|
+
}
|
541
|
+
return false;
|
542
|
+
};
|
543
|
+
/**
|
544
|
+
* disable a node's checkbox
|
545
|
+
* @name disable_checkbox(obj)
|
546
|
+
* @param {mixed} obj an array can be used too
|
547
|
+
* @trigger disable_checkbox.jstree
|
548
|
+
* @plugin checkbox
|
549
|
+
*/
|
550
|
+
this.disable_checkbox = function (obj) {
|
551
|
+
var t1, t2, dom;
|
552
|
+
if($.isArray(obj)) {
|
553
|
+
obj = obj.slice();
|
554
|
+
for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
|
555
|
+
this.disable_checkbox(obj[t1]);
|
556
|
+
}
|
557
|
+
return true;
|
558
|
+
}
|
559
|
+
obj = this.get_node(obj);
|
560
|
+
if(!obj || obj.id === $.jstree.root) {
|
561
|
+
return false;
|
562
|
+
}
|
563
|
+
dom = this.get_node(obj, true);
|
564
|
+
if(!obj.state.checkbox_disabled) {
|
565
|
+
obj.state.checkbox_disabled = true;
|
566
|
+
if(dom && dom.length) {
|
567
|
+
dom.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-checkbox-disabled');
|
568
|
+
}
|
569
|
+
/**
|
570
|
+
* triggered when an node's checkbox is disabled
|
571
|
+
* @event
|
572
|
+
* @name disable_checkbox.jstree
|
573
|
+
* @param {Object} node
|
574
|
+
* @plugin checkbox
|
575
|
+
*/
|
576
|
+
this.trigger('disable_checkbox', { 'node' : obj });
|
577
|
+
}
|
578
|
+
};
|
579
|
+
/**
|
580
|
+
* enable a node's checkbox
|
581
|
+
* @name enable_checkbox(obj)
|
582
|
+
* @param {mixed} obj an array can be used too
|
583
|
+
* @trigger enable_checkbox.jstree
|
584
|
+
* @plugin checkbox
|
585
|
+
*/
|
586
|
+
this.enable_checkbox = function (obj) {
|
587
|
+
var t1, t2, dom;
|
588
|
+
if($.isArray(obj)) {
|
589
|
+
obj = obj.slice();
|
590
|
+
for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
|
591
|
+
this.enable_checkbox(obj[t1]);
|
592
|
+
}
|
593
|
+
return true;
|
594
|
+
}
|
595
|
+
obj = this.get_node(obj);
|
596
|
+
if(!obj || obj.id === $.jstree.root) {
|
597
|
+
return false;
|
598
|
+
}
|
599
|
+
dom = this.get_node(obj, true);
|
600
|
+
if(obj.state.checkbox_disabled) {
|
601
|
+
obj.state.checkbox_disabled = false;
|
602
|
+
if(dom && dom.length) {
|
603
|
+
dom.children('.jstree-anchor').children('.jstree-checkbox').removeClass('jstree-checkbox-disabled');
|
604
|
+
}
|
605
|
+
/**
|
606
|
+
* triggered when an node's checkbox is enabled
|
607
|
+
* @event
|
608
|
+
* @name enable_checkbox.jstree
|
609
|
+
* @param {Object} node
|
610
|
+
* @plugin checkbox
|
611
|
+
*/
|
612
|
+
this.trigger('enable_checkbox', { 'node' : obj });
|
613
|
+
}
|
614
|
+
};
|
615
|
+
|
616
|
+
this.activate_node = function (obj, e) {
|
617
|
+
if($(e.target).hasClass('jstree-checkbox-disabled')) {
|
618
|
+
return false;
|
619
|
+
}
|
620
|
+
if(this.settings.checkbox.tie_selection && (this.settings.checkbox.whole_node || $(e.target).hasClass('jstree-checkbox'))) {
|
621
|
+
e.ctrlKey = true;
|
622
|
+
}
|
623
|
+
if(this.settings.checkbox.tie_selection || (!this.settings.checkbox.whole_node && !$(e.target).hasClass('jstree-checkbox'))) {
|
624
|
+
return parent.activate_node.call(this, obj, e);
|
625
|
+
}
|
626
|
+
if(this.is_disabled(obj)) {
|
627
|
+
return false;
|
628
|
+
}
|
629
|
+
if(this.is_checked(obj)) {
|
630
|
+
this.uncheck_node(obj, e);
|
631
|
+
}
|
632
|
+
else {
|
633
|
+
this.check_node(obj, e);
|
634
|
+
}
|
635
|
+
this.trigger('activate_node', { 'node' : this.get_node(obj) });
|
636
|
+
};
|
637
|
+
|
638
|
+
/**
|
639
|
+
* Cascades checked state to a node and all its descendants. This function does NOT affect hidden and disabled nodes (or their descendants).
|
640
|
+
* However if these unaffected nodes are already selected their ids will be included in the returned array.
|
641
|
+
* @private
|
642
|
+
* @param {string} id the node ID
|
643
|
+
* @param {bool} checkedState should the nodes be checked or not
|
644
|
+
* @returns {Array} Array of all node id's (in this tree branch) that are checked.
|
645
|
+
*/
|
646
|
+
this._cascade_new_checked_state = function (id, checkedState) {
|
647
|
+
var self = this;
|
648
|
+
var t = this.settings.checkbox.tie_selection;
|
649
|
+
var node = this._model.data[id];
|
650
|
+
var selectedNodeIds = [];
|
651
|
+
var selectedChildrenIds = [], i, j, selectedChildIds;
|
652
|
+
|
653
|
+
if (
|
654
|
+
(this.settings.checkbox.cascade_to_disabled || !node.state.disabled) &&
|
655
|
+
(this.settings.checkbox.cascade_to_hidden || !node.state.hidden)
|
656
|
+
) {
|
657
|
+
//First try and check/uncheck the children
|
658
|
+
if (node.children) {
|
659
|
+
for (i = 0, j = node.children.length; i < j; i++) {
|
660
|
+
var childId = node.children[i];
|
661
|
+
selectedChildIds = self._cascade_new_checked_state(childId, checkedState);
|
662
|
+
selectedNodeIds = selectedNodeIds.concat(selectedChildIds);
|
663
|
+
if (selectedChildIds.indexOf(childId) > -1) {
|
664
|
+
selectedChildrenIds.push(childId);
|
665
|
+
}
|
666
|
+
}
|
667
|
+
}
|
668
|
+
|
669
|
+
var dom = self.get_node(node, true);
|
670
|
+
|
671
|
+
//A node's state is undetermined if some but not all of it's children are checked/selected .
|
672
|
+
var undetermined = selectedChildrenIds.length > 0 && selectedChildrenIds.length < node.children.length;
|
673
|
+
|
674
|
+
if(node.original && node.original.state && node.original.state.undetermined) {
|
675
|
+
node.original.state.undetermined = undetermined;
|
676
|
+
}
|
677
|
+
|
678
|
+
//If a node is undetermined then remove selected class
|
679
|
+
if (undetermined) {
|
680
|
+
node.state[ t ? 'selected' : 'checked' ] = false;
|
681
|
+
dom.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked');
|
682
|
+
}
|
683
|
+
//Otherwise, if the checkedState === true (i.e. the node is being checked now) and all of the node's children are checked (if it has any children),
|
684
|
+
//check the node and style it correctly.
|
685
|
+
else if (checkedState && selectedChildrenIds.length === node.children.length) {
|
686
|
+
node.state[ t ? 'selected' : 'checked' ] = checkedState;
|
687
|
+
selectedNodeIds.push(node.id);
|
688
|
+
|
689
|
+
dom.attr('aria-selected', true).children('.jstree-anchor').addClass(t ? 'jstree-clicked' : 'jstree-checked');
|
690
|
+
}
|
691
|
+
else {
|
692
|
+
node.state[ t ? 'selected' : 'checked' ] = false;
|
693
|
+
dom.attr('aria-selected', false).children('.jstree-anchor').removeClass(t ? 'jstree-clicked' : 'jstree-checked');
|
694
|
+
}
|
695
|
+
}
|
696
|
+
else {
|
697
|
+
selectedChildIds = this.get_checked_descendants(id);
|
698
|
+
|
699
|
+
if (node.state[ t ? 'selected' : 'checked' ]) {
|
700
|
+
selectedChildIds.push(node.id);
|
701
|
+
}
|
702
|
+
|
703
|
+
selectedNodeIds = selectedNodeIds.concat(selectedChildIds);
|
704
|
+
}
|
705
|
+
|
706
|
+
return selectedNodeIds;
|
707
|
+
};
|
708
|
+
|
709
|
+
/**
|
710
|
+
* Gets ids of nodes selected in branch (of tree) specified by id (does not include the node specified by id)
|
711
|
+
* @name get_checked_descendants(obj)
|
712
|
+
* @param {string} id the node ID
|
713
|
+
* @return {Array} array of IDs
|
714
|
+
* @plugin checkbox
|
715
|
+
*/
|
716
|
+
this.get_checked_descendants = function (id) {
|
717
|
+
var self = this;
|
718
|
+
var t = self.settings.checkbox.tie_selection;
|
719
|
+
var node = self._model.data[id];
|
720
|
+
|
721
|
+
return $.vakata.array_filter(node.children_d, function(_id) {
|
722
|
+
return self._model.data[_id].state[ t ? 'selected' : 'checked' ];
|
723
|
+
});
|
724
|
+
};
|
725
|
+
|
726
|
+
/**
|
727
|
+
* check a node (only if tie_selection in checkbox settings is false, otherwise select_node will be called internally)
|
728
|
+
* @name check_node(obj)
|
729
|
+
* @param {mixed} obj an array can be used to check multiple nodes
|
730
|
+
* @trigger check_node.jstree
|
731
|
+
* @plugin checkbox
|
732
|
+
*/
|
733
|
+
this.check_node = function (obj, e) {
|
734
|
+
if(this.settings.checkbox.tie_selection) { return this.select_node(obj, false, true, e); }
|
735
|
+
var dom, t1, t2, th;
|
736
|
+
if($.isArray(obj)) {
|
737
|
+
obj = obj.slice();
|
738
|
+
for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
|
739
|
+
this.check_node(obj[t1], e);
|
740
|
+
}
|
741
|
+
return true;
|
742
|
+
}
|
743
|
+
obj = this.get_node(obj);
|
744
|
+
if(!obj || obj.id === $.jstree.root) {
|
745
|
+
return false;
|
746
|
+
}
|
747
|
+
dom = this.get_node(obj, true);
|
748
|
+
if(!obj.state.checked) {
|
749
|
+
obj.state.checked = true;
|
750
|
+
this._data.checkbox.selected.push(obj.id);
|
751
|
+
if(dom && dom.length) {
|
752
|
+
dom.children('.jstree-anchor').addClass('jstree-checked');
|
753
|
+
}
|
754
|
+
/**
|
755
|
+
* triggered when an node is checked (only if tie_selection in checkbox settings is false)
|
756
|
+
* @event
|
757
|
+
* @name check_node.jstree
|
758
|
+
* @param {Object} node
|
759
|
+
* @param {Array} selected the current selection
|
760
|
+
* @param {Object} event the event (if any) that triggered this check_node
|
761
|
+
* @plugin checkbox
|
762
|
+
*/
|
763
|
+
this.trigger('check_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e });
|
764
|
+
}
|
765
|
+
};
|
766
|
+
/**
|
767
|
+
* uncheck a node (only if tie_selection in checkbox settings is false, otherwise deselect_node will be called internally)
|
768
|
+
* @name uncheck_node(obj)
|
769
|
+
* @param {mixed} obj an array can be used to uncheck multiple nodes
|
770
|
+
* @trigger uncheck_node.jstree
|
771
|
+
* @plugin checkbox
|
772
|
+
*/
|
773
|
+
this.uncheck_node = function (obj, e) {
|
774
|
+
if(this.settings.checkbox.tie_selection) { return this.deselect_node(obj, false, e); }
|
775
|
+
var t1, t2, dom;
|
776
|
+
if($.isArray(obj)) {
|
777
|
+
obj = obj.slice();
|
778
|
+
for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
|
779
|
+
this.uncheck_node(obj[t1], e);
|
780
|
+
}
|
781
|
+
return true;
|
782
|
+
}
|
783
|
+
obj = this.get_node(obj);
|
784
|
+
if(!obj || obj.id === $.jstree.root) {
|
785
|
+
return false;
|
786
|
+
}
|
787
|
+
dom = this.get_node(obj, true);
|
788
|
+
if(obj.state.checked) {
|
789
|
+
obj.state.checked = false;
|
790
|
+
this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, obj.id);
|
791
|
+
if(dom.length) {
|
792
|
+
dom.children('.jstree-anchor').removeClass('jstree-checked');
|
793
|
+
}
|
794
|
+
/**
|
795
|
+
* triggered when an node is unchecked (only if tie_selection in checkbox settings is false)
|
796
|
+
* @event
|
797
|
+
* @name uncheck_node.jstree
|
798
|
+
* @param {Object} node
|
799
|
+
* @param {Array} selected the current selection
|
800
|
+
* @param {Object} event the event (if any) that triggered this uncheck_node
|
801
|
+
* @plugin checkbox
|
802
|
+
*/
|
803
|
+
this.trigger('uncheck_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e });
|
804
|
+
}
|
805
|
+
};
|
806
|
+
|
807
|
+
/**
|
808
|
+
* checks all nodes in the tree (only if tie_selection in checkbox settings is false, otherwise select_all will be called internally)
|
809
|
+
* @name check_all()
|
810
|
+
* @trigger check_all.jstree, changed.jstree
|
811
|
+
* @plugin checkbox
|
812
|
+
*/
|
813
|
+
this.check_all = function () {
|
814
|
+
if(this.settings.checkbox.tie_selection) { return this.select_all(); }
|
815
|
+
var tmp = this._data.checkbox.selected.concat([]), i, j;
|
816
|
+
this._data.checkbox.selected = this._model.data[$.jstree.root].children_d.concat();
|
817
|
+
for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) {
|
818
|
+
if(this._model.data[this._data.checkbox.selected[i]]) {
|
819
|
+
this._model.data[this._data.checkbox.selected[i]].state.checked = true;
|
820
|
+
}
|
821
|
+
}
|
822
|
+
this.redraw(true);
|
823
|
+
/**
|
824
|
+
* triggered when all nodes are checked (only if tie_selection in checkbox settings is false)
|
825
|
+
* @event
|
826
|
+
* @name check_all.jstree
|
827
|
+
* @param {Array} selected the current selection
|
828
|
+
* @plugin checkbox
|
829
|
+
*/
|
830
|
+
this.trigger('check_all', { 'selected' : this._data.checkbox.selected });
|
831
|
+
};
|
832
|
+
/**
|
833
|
+
* uncheck all checked nodes (only if tie_selection in checkbox settings is false, otherwise deselect_all will be called internally)
|
834
|
+
* @name uncheck_all()
|
835
|
+
* @trigger uncheck_all.jstree
|
836
|
+
* @plugin checkbox
|
837
|
+
*/
|
838
|
+
this.uncheck_all = function () {
|
839
|
+
if(this.settings.checkbox.tie_selection) { return this.deselect_all(); }
|
840
|
+
var tmp = this._data.checkbox.selected.concat([]), i, j;
|
841
|
+
for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) {
|
842
|
+
if(this._model.data[this._data.checkbox.selected[i]]) {
|
843
|
+
this._model.data[this._data.checkbox.selected[i]].state.checked = false;
|
844
|
+
}
|
845
|
+
}
|
846
|
+
this._data.checkbox.selected = [];
|
847
|
+
this.element.find('.jstree-checked').removeClass('jstree-checked');
|
848
|
+
/**
|
849
|
+
* triggered when all nodes are unchecked (only if tie_selection in checkbox settings is false)
|
850
|
+
* @event
|
851
|
+
* @name uncheck_all.jstree
|
852
|
+
* @param {Object} node the previous selection
|
853
|
+
* @param {Array} selected the current selection
|
854
|
+
* @plugin checkbox
|
855
|
+
*/
|
856
|
+
this.trigger('uncheck_all', { 'selected' : this._data.checkbox.selected, 'node' : tmp });
|
857
|
+
};
|
858
|
+
/**
|
859
|
+
* checks if a node is checked (if tie_selection is on in the settings this function will return the same as is_selected)
|
860
|
+
* @name is_checked(obj)
|
861
|
+
* @param {mixed} obj
|
862
|
+
* @return {Boolean}
|
863
|
+
* @plugin checkbox
|
864
|
+
*/
|
865
|
+
this.is_checked = function (obj) {
|
866
|
+
if(this.settings.checkbox.tie_selection) { return this.is_selected(obj); }
|
867
|
+
obj = this.get_node(obj);
|
868
|
+
if(!obj || obj.id === $.jstree.root) { return false; }
|
869
|
+
return obj.state.checked;
|
870
|
+
};
|
871
|
+
/**
|
872
|
+
* get an array of all checked nodes (if tie_selection is on in the settings this function will return the same as get_selected)
|
873
|
+
* @name get_checked([full])
|
874
|
+
* @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
|
875
|
+
* @return {Array}
|
876
|
+
* @plugin checkbox
|
877
|
+
*/
|
878
|
+
this.get_checked = function (full) {
|
879
|
+
if(this.settings.checkbox.tie_selection) { return this.get_selected(full); }
|
880
|
+
return full ? $.map(this._data.checkbox.selected, $.proxy(function (i) { return this.get_node(i); }, this)) : this._data.checkbox.selected.slice();
|
881
|
+
};
|
882
|
+
/**
|
883
|
+
* get an array of all top level checked nodes (ignoring children of checked nodes) (if tie_selection is on in the settings this function will return the same as get_top_selected)
|
884
|
+
* @name get_top_checked([full])
|
885
|
+
* @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
|
886
|
+
* @return {Array}
|
887
|
+
* @plugin checkbox
|
888
|
+
*/
|
889
|
+
this.get_top_checked = function (full) {
|
890
|
+
if(this.settings.checkbox.tie_selection) { return this.get_top_selected(full); }
|
891
|
+
var tmp = this.get_checked(true),
|
892
|
+
obj = {}, i, j, k, l;
|
893
|
+
for(i = 0, j = tmp.length; i < j; i++) {
|
894
|
+
obj[tmp[i].id] = tmp[i];
|
895
|
+
}
|
896
|
+
for(i = 0, j = tmp.length; i < j; i++) {
|
897
|
+
for(k = 0, l = tmp[i].children_d.length; k < l; k++) {
|
898
|
+
if(obj[tmp[i].children_d[k]]) {
|
899
|
+
delete obj[tmp[i].children_d[k]];
|
900
|
+
}
|
901
|
+
}
|
902
|
+
}
|
903
|
+
tmp = [];
|
904
|
+
for(i in obj) {
|
905
|
+
if(obj.hasOwnProperty(i)) {
|
906
|
+
tmp.push(i);
|
907
|
+
}
|
908
|
+
}
|
909
|
+
return full ? $.map(tmp, $.proxy(function (i) { return this.get_node(i); }, this)) : tmp;
|
910
|
+
};
|
911
|
+
/**
|
912
|
+
* get an array of all bottom level checked nodes (ignoring selected parents) (if tie_selection is on in the settings this function will return the same as get_bottom_selected)
|
913
|
+
* @name get_bottom_checked([full])
|
914
|
+
* @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned
|
915
|
+
* @return {Array}
|
916
|
+
* @plugin checkbox
|
917
|
+
*/
|
918
|
+
this.get_bottom_checked = function (full) {
|
919
|
+
if(this.settings.checkbox.tie_selection) { return this.get_bottom_selected(full); }
|
920
|
+
var tmp = this.get_checked(true),
|
921
|
+
obj = [], i, j;
|
922
|
+
for(i = 0, j = tmp.length; i < j; i++) {
|
923
|
+
if(!tmp[i].children.length) {
|
924
|
+
obj.push(tmp[i].id);
|
925
|
+
}
|
926
|
+
}
|
927
|
+
return full ? $.map(obj, $.proxy(function (i) { return this.get_node(i); }, this)) : obj;
|
928
|
+
};
|
929
|
+
this.load_node = function (obj, callback) {
|
930
|
+
var k, l, i, j, c, tmp;
|
931
|
+
if(!$.isArray(obj) && !this.settings.checkbox.tie_selection) {
|
932
|
+
tmp = this.get_node(obj);
|
933
|
+
if(tmp && tmp.state.loaded) {
|
934
|
+
for(k = 0, l = tmp.children_d.length; k < l; k++) {
|
935
|
+
if(this._model.data[tmp.children_d[k]].state.checked) {
|
936
|
+
c = true;
|
937
|
+
this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, tmp.children_d[k]);
|
938
|
+
}
|
939
|
+
}
|
940
|
+
}
|
941
|
+
}
|
942
|
+
return parent.load_node.apply(this, arguments);
|
943
|
+
};
|
944
|
+
this.get_state = function () {
|
945
|
+
var state = parent.get_state.apply(this, arguments);
|
946
|
+
if(this.settings.checkbox.tie_selection) { return state; }
|
947
|
+
state.checkbox = this._data.checkbox.selected.slice();
|
948
|
+
return state;
|
949
|
+
};
|
950
|
+
this.set_state = function (state, callback) {
|
951
|
+
var res = parent.set_state.apply(this, arguments);
|
952
|
+
if(res && state.checkbox) {
|
953
|
+
if(!this.settings.checkbox.tie_selection) {
|
954
|
+
this.uncheck_all();
|
955
|
+
var _this = this;
|
956
|
+
$.each(state.checkbox, function (i, v) {
|
957
|
+
_this.check_node(v);
|
958
|
+
});
|
959
|
+
}
|
960
|
+
delete state.checkbox;
|
961
|
+
this.set_state(state, callback);
|
962
|
+
return false;
|
963
|
+
}
|
964
|
+
return res;
|
965
|
+
};
|
966
|
+
this.refresh = function (skip_loading, forget_state) {
|
967
|
+
if(this.settings.checkbox.tie_selection) {
|
968
|
+
this._data.checkbox.selected = [];
|
969
|
+
}
|
970
|
+
return parent.refresh.apply(this, arguments);
|
971
|
+
};
|
972
|
+
};
|
973
|
+
|
974
|
+
// include the checkbox plugin by default
|
975
|
+
// $.jstree.defaults.plugins.push("checkbox");
|
976
|
+
}));
|