jstree-rails 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/INSTALLER.sh +57 -0
- data/LICENSE +22 -0
- data/README.md +29 -0
- data/Rakefile +2 -0
- data/jstree-rails.gemspec +17 -0
- data/lib/jstree-rails/rails.rb +6 -0
- data/lib/jstree-rails/version.rb +5 -0
- data/lib/jstree-rails.rb +8 -0
- data/vendor/assets/images/jstree/themes/default/d.gif +0 -0
- data/vendor/assets/images/jstree/themes/default/d.png +0 -0
- data/vendor/assets/images/jstree/themes/default/throbber.gif +0 -0
- data/vendor/assets/images/jstree/themes/default-rtl/d.gif +0 -0
- data/vendor/assets/images/jstree/themes/default-rtl/d.png +0 -0
- data/vendor/assets/images/jstree/themes/default-rtl/dots.gif +0 -0
- data/vendor/assets/images/jstree/themes/default-rtl/throbber.gif +0 -0
- data/vendor/assets/javascripts/jstree/index.js +15 -0
- data/vendor/assets/javascripts/jstree/jstree.checkbox.js +187 -0
- data/vendor/assets/javascripts/jstree/jstree.contextmenu.js +145 -0
- data/vendor/assets/javascripts/jstree/jstree.dnd.js +162 -0
- data/vendor/assets/javascripts/jstree/jstree.hotkeys.js +138 -0
- data/vendor/assets/javascripts/jstree/jstree.html.js +69 -0
- data/vendor/assets/javascripts/jstree/jstree.js +1982 -0
- data/vendor/assets/javascripts/jstree/jstree.json.js +99 -0
- data/vendor/assets/javascripts/jstree/jstree.rules.js +145 -0
- data/vendor/assets/javascripts/jstree/jstree.sort.js +38 -0
- data/vendor/assets/javascripts/jstree/jstree.state.js +39 -0
- data/vendor/assets/javascripts/jstree/jstree.themes.js +215 -0
- data/vendor/assets/javascripts/jstree/jstree.ui.js +201 -0
- data/vendor/assets/javascripts/jstree/jstree.unique.js +33 -0
- data/vendor/assets/javascripts/jstree/jstree.xml.js +185 -0
- data/vendor/assets/javascripts/jstree/vakata.js +2079 -0
- data/vendor/assets/stylesheets/jstree/themes/default/style.css +79 -0
- data/vendor/assets/stylesheets/jstree/themes/default-rtl/style.css +84 -0
- metadata +80 -0
@@ -0,0 +1,1982 @@
|
|
1
|
+
/*
|
2
|
+
* jsTree 1.0.0
|
3
|
+
* http://jstree.com/
|
4
|
+
*
|
5
|
+
* Copyright (c) 2011 Ivan Bozhanov (vakata.com)
|
6
|
+
*
|
7
|
+
* Licensed same as jquery - under the terms of either the MIT License or the GPL Version 2 License
|
8
|
+
* http://www.opensource.org/licenses/mit-license.php
|
9
|
+
* http://www.gnu.org/licenses/gpl.html
|
10
|
+
*
|
11
|
+
*/
|
12
|
+
|
13
|
+
/*global jQuery */
|
14
|
+
|
15
|
+
/* File: jstree.js
|
16
|
+
The only required part of jstree it consists of a few functions bound to the $.jstree object, the actual plugin function and a few core functions for manipulating a tree.
|
17
|
+
*/
|
18
|
+
(function () {
|
19
|
+
"use strict";
|
20
|
+
if(!jQuery) { throw "jsTree: jQuery not included."; }
|
21
|
+
if(jQuery.jstree) { return; } // prevent another load? maybe there is a better way?
|
22
|
+
|
23
|
+
/* Group: $.jstree.
|
24
|
+
Some static functions and variables, unless you know exactly what you are doing do not use these, but <$().jstree> instead.
|
25
|
+
*/
|
26
|
+
(function ($) {
|
27
|
+
var instances = [],
|
28
|
+
focused_instance = -1,
|
29
|
+
plugins = {},
|
30
|
+
functions = {};
|
31
|
+
/*
|
32
|
+
Variable: $.jstree
|
33
|
+
*object* Contains all static functions and variables used by jstree, some plugins also append variables.
|
34
|
+
*/
|
35
|
+
$.jstree = {
|
36
|
+
/*
|
37
|
+
Variable: $.jstree.VERSION
|
38
|
+
*string* the version of jstree
|
39
|
+
*/
|
40
|
+
VERSION : '1.0.0',
|
41
|
+
|
42
|
+
/*
|
43
|
+
Variable: $.jstree.IS_IE6
|
44
|
+
*boolean* indicating if the client is running Internet Explorer 6
|
45
|
+
*/
|
46
|
+
IS_IE6 : (jQuery.browser.msie && parseInt(jQuery.browser.version,10) === 6),
|
47
|
+
|
48
|
+
/*
|
49
|
+
Variable: $.jstree.IS_IE7
|
50
|
+
*boolean* indicating if the client is running Internet Explorer 7
|
51
|
+
*/
|
52
|
+
IS_IE7 : (jQuery.browser.msie && parseInt(jQuery.browser.version,10) === 6),
|
53
|
+
|
54
|
+
/*
|
55
|
+
Variable: $.jstree.IS_FF2
|
56
|
+
*boolean* indicating if the client is running Firefox 2
|
57
|
+
*/
|
58
|
+
IS_FF2 : (jQuery.browser.mozilla && parseFloat(jQuery.browser.version,10) < 1.9),
|
59
|
+
|
60
|
+
/*
|
61
|
+
Function: $.jstree.__construct
|
62
|
+
Creates a new jstree instance, any arguments after the first one are merged and used to configure the tree.
|
63
|
+
|
64
|
+
`.data("jstree")` is also called on the container and is used for configuration (keep in mind you can specify this data using a "data-jstree" attribute)
|
65
|
+
|
66
|
+
Parameters:
|
67
|
+
container - *mixed* the container of the tree (this should not be the UL node, but a wrapper) - DOM node, jQuery object or selector
|
68
|
+
*/
|
69
|
+
__construct : function (container) {
|
70
|
+
var s = {}, // settings
|
71
|
+
d = {}, // data
|
72
|
+
p = [], // plugins
|
73
|
+
t = [], // plugins temp
|
74
|
+
i = 0; // index
|
75
|
+
container = $(container);
|
76
|
+
if($.jstree._reference(container)) { $.jstree.__destruct(container); }
|
77
|
+
$.extend.apply(null, [true, s].concat(Array.prototype.slice.call(arguments, 1), (container.data("jstree") || {}) ));
|
78
|
+
p = $.isArray(s.plugins) ? s.plugins : $.jstree.defaults.plugins.slice();
|
79
|
+
p = $.vakata.array_unique(p);
|
80
|
+
s = $.extend(true, {}, $.jstree.defaults, s);
|
81
|
+
$.each(plugins, function (i, val) {
|
82
|
+
if(i !== "core" && $.inArray(i, p) === -1) { s[i] = null; delete s[i]; }
|
83
|
+
else { t.push(i); d[i] = {}; }
|
84
|
+
});
|
85
|
+
s.plugins = t;
|
86
|
+
i = parseInt(instances.push({}),10) - 1;
|
87
|
+
container
|
88
|
+
.data("jstree_instance_id", i)
|
89
|
+
.addClass("jstree jstree-" + i);
|
90
|
+
|
91
|
+
this.data = d;
|
92
|
+
this.get_index = function () { return i; };
|
93
|
+
this.get_container = function () { return container; };
|
94
|
+
this.get_container_ul = function () { return container.children("ul:eq(0)"); };
|
95
|
+
this.get_settings = function (writable) { return writable ? s : $.extend(true, {}, s); };
|
96
|
+
this.__trigger = function (ev, data) {
|
97
|
+
if(!ev) { return; }
|
98
|
+
if(!data) { data = {}; }
|
99
|
+
if(typeof ev === "string") { ev = ev.replace(".jstree","") + ".jstree"; }
|
100
|
+
data.inst = this;
|
101
|
+
this.get_container().triggerHandler(ev, data);
|
102
|
+
};
|
103
|
+
instances[i] = this;
|
104
|
+
$.each(t, function (j, val) { if(plugins[val]) { plugins[val].__construct.apply(instances[i]); } });
|
105
|
+
this.__trigger("__construct");
|
106
|
+
$.jstree._focus(i);
|
107
|
+
return this;
|
108
|
+
},
|
109
|
+
/*
|
110
|
+
Group: $.jstree.
|
111
|
+
|
112
|
+
Function: $.jstree.__destruct
|
113
|
+
Destroys an instance, and also clears `jstree-` prefixed classes and all events in the `jstree` namespace
|
114
|
+
|
115
|
+
Parameters:
|
116
|
+
instance - *mixed* the instance to destroy (this argument is passed to <$.jstree._reference> to get the instance)
|
117
|
+
|
118
|
+
See also:
|
119
|
+
<$.jstree._reference>
|
120
|
+
*/
|
121
|
+
__destruct : function (instance) {
|
122
|
+
instance = $.jstree._reference(instance);
|
123
|
+
if(!instance) { return false; }
|
124
|
+
var s = instance.get_settings(),
|
125
|
+
n = instance.get_index(),
|
126
|
+
i = 0;
|
127
|
+
if(focused_instance === n) {
|
128
|
+
for(i in instances) {
|
129
|
+
if(instances.hasOwnProperty(i) && i !== n) {
|
130
|
+
$.jstree._focus(i);
|
131
|
+
break;
|
132
|
+
}
|
133
|
+
}
|
134
|
+
if(focused_instance === n) { $.jstree._focus(false); }
|
135
|
+
}
|
136
|
+
$.each(s.plugins, function (i, val) {
|
137
|
+
try { plugins[val].__destruct.apply(instance); } catch(err) { }
|
138
|
+
});
|
139
|
+
instance.__trigger("__destruct");
|
140
|
+
instance.get_container()
|
141
|
+
.unbind(".jstree")
|
142
|
+
.undelegate(".jstree")
|
143
|
+
.removeData("jstree_instance_id")
|
144
|
+
.find("[class^='jstree']")
|
145
|
+
.andSelf()
|
146
|
+
.attr("class", function () { return this.className.replace(/jstree[^ ]*|$/ig,''); });
|
147
|
+
$(document)
|
148
|
+
.unbind(".jstree-" + n)
|
149
|
+
.undelegate(".jstree-" + n);
|
150
|
+
delete instances[n];
|
151
|
+
return true;
|
152
|
+
},
|
153
|
+
/*
|
154
|
+
Function: $.jstree.__call
|
155
|
+
Call a function on the instance and return the result
|
156
|
+
|
157
|
+
Parameters:
|
158
|
+
instance - *mixed* the instance to destroy (this argument is passed to <$.jstree._reference> to get the instance)
|
159
|
+
operation - *string* the operation to execute
|
160
|
+
args - *array* the arguments to pass to the function
|
161
|
+
|
162
|
+
See also:
|
163
|
+
<$.jstree._reference>
|
164
|
+
*/
|
165
|
+
__call : function (instance, operation, args) {
|
166
|
+
instance = $.jstree._reference(instance);
|
167
|
+
if(!instance || !$.isFunction(instance[operation])) { return; }
|
168
|
+
return instance[operation].apply(instance, args);
|
169
|
+
},
|
170
|
+
/*
|
171
|
+
Function: $.jstree._reference
|
172
|
+
Returns an instance
|
173
|
+
|
174
|
+
Parameters:
|
175
|
+
needle - *mixed* - integer, DOM node contained inside a jstree container, ID string, jQuery object, selector
|
176
|
+
*/
|
177
|
+
_reference : function (needle) {
|
178
|
+
if(instances[needle]) { return instances[needle]; }
|
179
|
+
var o = $(needle);
|
180
|
+
if(!o.length && typeof needle === "string") { o = $("#" + needle); }
|
181
|
+
if(!o.length) { return null; }
|
182
|
+
return instances[o.closest(".jstree").data("jstree_instance_id")] || null;
|
183
|
+
},
|
184
|
+
/*
|
185
|
+
Function: $.jstree._focused
|
186
|
+
Returns the currently focused instance (by default once an instance is created it is focused)
|
187
|
+
*/
|
188
|
+
_focused : function () {
|
189
|
+
return instances[focused_instance] || null;
|
190
|
+
},
|
191
|
+
/*
|
192
|
+
Function: $.jstree._focus
|
193
|
+
Make an instance focused (which defocuses the previously focused instance)
|
194
|
+
|
195
|
+
Parameters:
|
196
|
+
instance - *mixed* the instance to focus (this argument is passed to <$.jstree._reference> to get the instance)
|
197
|
+
|
198
|
+
See also:
|
199
|
+
<$.jstree._reference>
|
200
|
+
*/
|
201
|
+
_focus : function (instance) {
|
202
|
+
if(instance === false) {
|
203
|
+
instances[focused_instance].get_container().removeClass("jstree-focused");
|
204
|
+
instances[focused_instance].__trigger("_defocus");
|
205
|
+
focused_instance = -1;
|
206
|
+
return false;
|
207
|
+
}
|
208
|
+
instance = $.jstree._reference(instance);
|
209
|
+
if(!instance || instance.get_index() === focused_instance) { return false; }
|
210
|
+
if(focused_instance !== -1) {
|
211
|
+
instances[focused_instance].get_container().removeClass("jstree-focused");
|
212
|
+
instances[focused_instance].__trigger("_defocus");
|
213
|
+
}
|
214
|
+
focused_instance = instance.get_index();
|
215
|
+
instance.get_container().addClass("jstree-focused");
|
216
|
+
instance.__trigger("_focus");
|
217
|
+
return true;
|
218
|
+
},
|
219
|
+
/*
|
220
|
+
Function: $.jstree.plugin
|
221
|
+
Register a plugin
|
222
|
+
|
223
|
+
Parameters:
|
224
|
+
plugin_name - *string* the name of the new plugin (it will be used as a key in an object - make sure it is valid)
|
225
|
+
plugin_data - *object* consists of 4 keys. Default is:
|
226
|
+
>{
|
227
|
+
> __construct : $.noop, // this function will be executed when a new instance is created
|
228
|
+
> __destuct : $.noop, // this function will be executed when an instance is destroyed
|
229
|
+
> _fn : { }, // each key of this object should be a function that will extend the jstree prototype
|
230
|
+
> defaults : false // the default configuration for the plugin (if any)
|
231
|
+
>}
|
232
|
+
*/
|
233
|
+
plugin : function (plugin_name, plugin_data) {
|
234
|
+
plugin_data = $.extend({}, {
|
235
|
+
__construct : $.noop,
|
236
|
+
__destuct : $.noop,
|
237
|
+
_fn : { },
|
238
|
+
defaults : false
|
239
|
+
}, plugin_data);
|
240
|
+
plugins[plugin_name] = plugin_data;
|
241
|
+
$.jstree.defaults[plugin_name] = plugin_data.defaults;
|
242
|
+
$.each(plugin_data._fn, function (i, val) {
|
243
|
+
val.plugin = plugin_name;
|
244
|
+
val.old = functions[i];
|
245
|
+
functions[i] = function () {
|
246
|
+
var rslt,
|
247
|
+
func = val,
|
248
|
+
args = Array.prototype.slice.call(arguments),
|
249
|
+
evnt = new $.Event("before.jstree"),
|
250
|
+
plgn = this.get_settings(true).plugins;
|
251
|
+
|
252
|
+
do {
|
253
|
+
if(func && func.plugin && $.inArray(func.plugin, plgn) !== -1) { break; }
|
254
|
+
func = func.old;
|
255
|
+
} while(func);
|
256
|
+
if(!func) { return; }
|
257
|
+
|
258
|
+
if(i.indexOf("_") === 0) {
|
259
|
+
rslt = func.apply(this, args);
|
260
|
+
}
|
261
|
+
else {
|
262
|
+
rslt = this.__trigger(evnt, { "func" : i, "args" : args, "plugin" : func.plugin });
|
263
|
+
if(rslt === false) { return; }
|
264
|
+
rslt = func.apply(
|
265
|
+
$.extend({}, this, {
|
266
|
+
__callback : function (data) {
|
267
|
+
this.__trigger( i, { "args" : args, "rslt" : data, "plugin" : func.plugin });
|
268
|
+
return data;
|
269
|
+
},
|
270
|
+
__call_old : function (replace_arguments) {
|
271
|
+
return func.old.apply(this, (replace_arguments ? Array.prototype.slice.call(arguments, 1) : args ) );
|
272
|
+
}
|
273
|
+
}), args);
|
274
|
+
}
|
275
|
+
return rslt;
|
276
|
+
};
|
277
|
+
functions[i].old = val.old;
|
278
|
+
functions[i].plugin = plugin_name;
|
279
|
+
});
|
280
|
+
},
|
281
|
+
/*
|
282
|
+
Variable: $.jstree.defaults
|
283
|
+
*object* storing all the default configuration options for every plugin and the core.
|
284
|
+
If this is modified all instances created after the modification, which do not explicitly specify some other value will use the new default.
|
285
|
+
|
286
|
+
Example:
|
287
|
+
>// this instance will use the _default_ theme
|
288
|
+
>$("#div0").jstree({ plugins : ["themes"] });
|
289
|
+
>$.jstree.defaults.themes.theme = "classic";
|
290
|
+
>// this instance will use the _classic_ theme
|
291
|
+
>$("#div1").jstree({ plugins : ["themes"] });
|
292
|
+
>// this instance will use the _apple_ theme
|
293
|
+
>$("#div2").jstree({ themes : { "theme" : "apple" }, plugins : ["themes"] });
|
294
|
+
*/
|
295
|
+
defaults : {
|
296
|
+
plugins : []
|
297
|
+
}
|
298
|
+
};
|
299
|
+
/* Group: $().jstree()
|
300
|
+
The actual plugin wrapper, use this to create instances or execute functions on created instances.
|
301
|
+
|
302
|
+
Function: $().jstree
|
303
|
+
|
304
|
+
Creates an instance using the specified objects for containers, or executes a command on an instance, specified by a container.
|
305
|
+
|
306
|
+
Parameters:
|
307
|
+
settings - *mixed*
|
308
|
+
|
309
|
+
- if you pass an *object* a new instance will be created (using <$.jstree.__construct>)
|
310
|
+
for each of the objects in the jquery collection,
|
311
|
+
if an instance already exists on the container it will be destroyed first
|
312
|
+
|
313
|
+
- if you pass a *string* it will be executed using <$.jstree.__call> on each instance
|
314
|
+
|
315
|
+
Examples:
|
316
|
+
> // this creates an instance
|
317
|
+
> $("#some-id").jstree({
|
318
|
+
> plugins : [ "html_data", "themes", "ui" ]
|
319
|
+
> });
|
320
|
+
>
|
321
|
+
> // this executes a function on the instance
|
322
|
+
> $("#some-id").jstree("select_node", "#the-id-to-select");
|
323
|
+
|
324
|
+
See also:
|
325
|
+
<$.jstree.__construct>,
|
326
|
+
<$.jstree.__destruct>,
|
327
|
+
<$.jstree.__call>
|
328
|
+
*/
|
329
|
+
$.fn.jstree = function (settings) {
|
330
|
+
var _is_method = (typeof settings === 'string'),
|
331
|
+
_arguments = Array.prototype.slice.call(arguments, 1),
|
332
|
+
_return = this;
|
333
|
+
this.each(function () {
|
334
|
+
if(_is_method) {
|
335
|
+
var val = $.jstree.__call(this, settings, _arguments);
|
336
|
+
if(typeof val !== "undefined" && (settings.indexOf("is_" === 0) || (val !== true && val !== false))) {
|
337
|
+
_return = val;
|
338
|
+
return false;
|
339
|
+
}
|
340
|
+
}
|
341
|
+
else {
|
342
|
+
_is_method = new $.jstree.__construct(this, settings);
|
343
|
+
}
|
344
|
+
});
|
345
|
+
return _return;
|
346
|
+
};
|
347
|
+
functions = $.jstree.__construct.prototype;
|
348
|
+
|
349
|
+
$.expr[':'].jstree = function(a,i,m) {
|
350
|
+
return typeof ($(a).data("jstree_instance_id")) !== 'undefined';
|
351
|
+
};
|
352
|
+
})(jQuery);
|
353
|
+
|
354
|
+
(function ($) {
|
355
|
+
var ccp_node = false,
|
356
|
+
ccp_mode = false;
|
357
|
+
|
358
|
+
$(function() { $.jstree.SCROLLBAR_WIDTH = $.vakata.get_scrollbar_width(); });
|
359
|
+
|
360
|
+
$.jstree.plugin("core", {
|
361
|
+
__construct : function () {
|
362
|
+
this.data.core.rtl = (this.get_container().css("direction") === "rtl");
|
363
|
+
if(this.data.core.rtl) { this.get_container().addClass("jstree-rtl"); }
|
364
|
+
this.data.core.ready = false;
|
365
|
+
|
366
|
+
this.get_container()
|
367
|
+
.bind("__construct.jstree", $.proxy(function () {
|
368
|
+
// defer, so that events bound AFTER creating the instance (like __ready) are still handled
|
369
|
+
setTimeout($.proxy(function () { if(this) { this.init(); } }, this), 0);
|
370
|
+
}, this))
|
371
|
+
.bind("before.jstree", $.proxy(function (e, data) {
|
372
|
+
if(!/^is_locked|unlock$/.test(data.func) && this.data.core.locked) {
|
373
|
+
e.stopImmediatePropagation();
|
374
|
+
return false;
|
375
|
+
}
|
376
|
+
}, this))
|
377
|
+
.bind("create_node.jstree", $.proxy(function (e, data) {
|
378
|
+
this.clean_node(data.rslt.obj);
|
379
|
+
}, this))
|
380
|
+
.bind("load_node.jstree", $.proxy(function (e, data) {
|
381
|
+
// data.rslt.status
|
382
|
+
this.clean_node(data.rslt.obj === -1 ? this.get_container_ul().children('li') : data.rslt.obj.find('> ul > li'));
|
383
|
+
if(!this.data.core.ready && !this.get_container_ul().find('.jstree-loading:eq(0)').length) {
|
384
|
+
this.data.core.ready = true;
|
385
|
+
this.__trigger("__ready");
|
386
|
+
}
|
387
|
+
}, this))
|
388
|
+
.bind("__loaded.jstree", $.proxy(function (e, data) {
|
389
|
+
data.inst.get_container_ul().children('li').each(function () {
|
390
|
+
data.inst.correct_node(this);
|
391
|
+
});
|
392
|
+
}, this))
|
393
|
+
.bind("open_node.jstree", $.proxy(function (e, data) {
|
394
|
+
data.rslt.obj.find('> ul > li').each(function () {
|
395
|
+
data.inst.correct_node(this);
|
396
|
+
});
|
397
|
+
}, this))
|
398
|
+
.bind("mousedown.jstree", $.proxy(function () {
|
399
|
+
$.jstree._focus(this.get_index());
|
400
|
+
}, this))
|
401
|
+
.bind("dblclick.jstree", function () {
|
402
|
+
if(document.selection && document.selection.empty) { document.selection.empty(); }
|
403
|
+
else { if(window.getSelection) { var sel = window.getSelection(); try { sel.removeAllRanges(); sel.collapse(); } catch (er) { } } }
|
404
|
+
})
|
405
|
+
.delegate("li > ins", "click.jstree", $.proxy(function (e) {
|
406
|
+
// var trgt = $(e.target);
|
407
|
+
// if(trgt.is("ins") && e.pageY - trgt.offset().top < this.data.core.li_height) { this.toggle_node(trgt); }
|
408
|
+
this.toggle_node(e.target);
|
409
|
+
}, this));
|
410
|
+
},
|
411
|
+
__destruct : function () {
|
412
|
+
|
413
|
+
},
|
414
|
+
/* Class: jstree */
|
415
|
+
/*
|
416
|
+
Variable: data
|
417
|
+
*object* Provides storage for plugins (aside from private variables). Every plugin has an key in this object.
|
418
|
+
> this.data.<plugin_name>;
|
419
|
+
This is useful for detecting if some plugin is included in the instance (plugins also use this for dependencies and enhancements).
|
420
|
+
|
421
|
+
Function: get_index
|
422
|
+
Returns an *integer*, which is the instance's index. Every instance on the page has an unique index, when destroying an intance the index will not be reused.
|
423
|
+
|
424
|
+
Function: get_container
|
425
|
+
Returns the jQuery extended container of the tree (the element you used when constructing the tree).
|
426
|
+
|
427
|
+
Function: get_container_ul
|
428
|
+
Returns the jQuery extended first UL node inside the container of the tree.
|
429
|
+
|
430
|
+
Function: get_settings
|
431
|
+
Returns the settings for the tree.
|
432
|
+
|
433
|
+
Parameters:
|
434
|
+
writable - *boolean* whether to return a copy of the settings object or a reference to it.
|
435
|
+
|
436
|
+
Example:
|
437
|
+
> $("#div1").jstree("get_settings"); // will return a copy
|
438
|
+
> $.jstree._reference("#div1").get_settings(); // same as above
|
439
|
+
> $.jstree._focused().get_settings(true); // a reference. BE CAREFUL!
|
440
|
+
|
441
|
+
Function: __trigger
|
442
|
+
Used internally to trigger events on the container node.
|
443
|
+
|
444
|
+
Parameters:
|
445
|
+
event_name - the name of the event to trigger (the *jstree* namespace will be appended to it)
|
446
|
+
data - the additional object to pass along with the event. By default _data.inst_ will be the current instance, so when you bind to the event, you can access the instance easily.
|
447
|
+
> $("div").bind("some-event.jstree", function (e, data) { data.inst.some_function(); });
|
448
|
+
*/
|
449
|
+
/*
|
450
|
+
Group: CORE options
|
451
|
+
|
452
|
+
Variable: config.core.strings
|
453
|
+
*mixed* used to store all localization strings. Default is _false_.
|
454
|
+
|
455
|
+
Example 1:
|
456
|
+
>$("div").jstree({
|
457
|
+
> core : {
|
458
|
+
> strings : function (s) {
|
459
|
+
> if(s === "Loading ...") { s = "Please wait ..."; }
|
460
|
+
> return s;
|
461
|
+
> }
|
462
|
+
> }
|
463
|
+
>});
|
464
|
+
|
465
|
+
Example 2:
|
466
|
+
>$("div").jstree({
|
467
|
+
> core : {
|
468
|
+
> strings : {
|
469
|
+
> "Loading ..." : "Please wait ..."
|
470
|
+
> }
|
471
|
+
> }
|
472
|
+
>});
|
473
|
+
|
474
|
+
See also:
|
475
|
+
<_get_string>
|
476
|
+
*/
|
477
|
+
defaults : {
|
478
|
+
strings : false
|
479
|
+
},
|
480
|
+
_fn : {
|
481
|
+
/*
|
482
|
+
Group: CORE functions
|
483
|
+
|
484
|
+
Function: _get_string
|
485
|
+
Used to get the common string in the tree.
|
486
|
+
|
487
|
+
If <config.core.strings> is set to a function, that function is called with a single parameter (the needed string), the response is returned.
|
488
|
+
|
489
|
+
If <config.core.strings> is set to an object, the key named as the needed string is returned.
|
490
|
+
|
491
|
+
If <config.core.strings> is not set, the the needed string is returned.
|
492
|
+
|
493
|
+
Parameters:
|
494
|
+
needed_string - *string* the needed string
|
495
|
+
*/
|
496
|
+
_get_string : function (s) {
|
497
|
+
var a = this.get_settings(true).core.strings;
|
498
|
+
if($.isFunction(a)) { return a.call(this, s); }
|
499
|
+
if(a && a[s]) { return a[s]; }
|
500
|
+
return s;
|
501
|
+
},
|
502
|
+
/*
|
503
|
+
Function: init
|
504
|
+
Used internally. This function is called once the core plugin is constructed.
|
505
|
+
|
506
|
+
Triggers:
|
507
|
+
<__loaded>
|
508
|
+
|
509
|
+
Event: __loaded
|
510
|
+
This event is triggered in the *jstree* namespace when data is first rendered in the tree. It won't be triggered after a refresh. Fires only once.
|
511
|
+
|
512
|
+
Parameters:
|
513
|
+
data.inst - the instance
|
514
|
+
|
515
|
+
Example:
|
516
|
+
> $("div").bind("__loaded.jstree", function (e, data) { data.inst.do_something(); });
|
517
|
+
|
518
|
+
Event: __ready
|
519
|
+
This event is triggered in the *jstree* namespace when all initial loading is done. It won't be triggered after a refresh. Fires only once.
|
520
|
+
|
521
|
+
Parameters:
|
522
|
+
data.inst - the instance
|
523
|
+
*/
|
524
|
+
init : function () {
|
525
|
+
this.data.core.original_container_html = this.get_container().find(" > ul > li").clone(true);
|
526
|
+
this.data.core.original_container_html.find("li").andSelf().contents().filter(function() { return this.nodeType === 3 && (!this.nodeValue || /^\s+$/.test(this.nodeValue)); }).remove();
|
527
|
+
this.get_container().html("<ul><li class='jstree-loading'><a href='#'>" + this._get_string("Loading ...") + "</a></li></ul>");
|
528
|
+
this.clean_node(-1);
|
529
|
+
this.data.core.li_height = this.get_container_ul().children("li:eq(0)").height() || 18;
|
530
|
+
this.load_node(-1, function () {
|
531
|
+
this.__trigger("__loaded");
|
532
|
+
});
|
533
|
+
},
|
534
|
+
/*
|
535
|
+
Function: lock
|
536
|
+
Used to lock the tree. When the tree is in a locked state, no functions can be called on the instance (except <is_locked> and <unlock>).
|
537
|
+
Additionally a _jstree-locked_ class is applied on the container.
|
538
|
+
|
539
|
+
Triggers:
|
540
|
+
<lock>
|
541
|
+
|
542
|
+
Event: lock
|
543
|
+
This event is triggered in the *jstree* namespace when the tree is locked.
|
544
|
+
|
545
|
+
Parameters:
|
546
|
+
data.inst - the instance
|
547
|
+
data.args - *array* the arguments passed to the function
|
548
|
+
data.plugin - *string* the function's plugin (here it will be _"core"_ but if the function is extended it may be something else).
|
549
|
+
data.rslt - _null_
|
550
|
+
|
551
|
+
Example:
|
552
|
+
> $("div").bind("lock.jstree", function (e, data) { data.inst.do_something(); });
|
553
|
+
*/
|
554
|
+
lock : function () {
|
555
|
+
this.data.core.locked = true;
|
556
|
+
this.get_container().addClass("jstree-locked");
|
557
|
+
this.__callback();
|
558
|
+
},
|
559
|
+
/*
|
560
|
+
Function: unlock
|
561
|
+
Used to unlock the tree. Instance can be used normally again. The _jstree-locked_ class is removed from the container.
|
562
|
+
|
563
|
+
Triggers:
|
564
|
+
<unlock>
|
565
|
+
|
566
|
+
Event: unlock
|
567
|
+
This event is triggered in the *jstree* namespace when the tree is unlocked.
|
568
|
+
|
569
|
+
Parameters:
|
570
|
+
data.inst - the instance
|
571
|
+
data.args - *array* the arguments passed to the function
|
572
|
+
data.plugin - *string* the function's plugin (here it will be _"core"_ but if the function is extended it may be something else).
|
573
|
+
data.rslt - _null_
|
574
|
+
|
575
|
+
Example:
|
576
|
+
> $("div").bind("unlock.jstree", function (e, data) { data.inst.do_something(); });
|
577
|
+
*/
|
578
|
+
unlock : function () {
|
579
|
+
this.data.core.locked = false;
|
580
|
+
this.get_container().removeClass("jstree-locked");
|
581
|
+
this.__callback();
|
582
|
+
},
|
583
|
+
/*
|
584
|
+
Function: is_locked
|
585
|
+
Used to get the locked status of the tree.
|
586
|
+
|
587
|
+
Returns:
|
588
|
+
locked - *boolean* _true_ if tree is locked, _false_ otherwise
|
589
|
+
*/
|
590
|
+
is_locked : function () {
|
591
|
+
return this.data.core.locked;
|
592
|
+
},
|
593
|
+
/*
|
594
|
+
Function: get_node
|
595
|
+
Get a hold of the LI node (which represents the jstree node).
|
596
|
+
|
597
|
+
Parameters:
|
598
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc.
|
599
|
+
|
600
|
+
Returns:
|
601
|
+
jquery collection - node was found, the collection contains the LI node
|
602
|
+
-1 - the tree container was referenced
|
603
|
+
false - on failure (obj is not part of a tree, or does not exists in the DOM)
|
604
|
+
*/
|
605
|
+
get_node : function (obj) {
|
606
|
+
var $obj = $(obj, this.get_container());
|
607
|
+
if($obj.is(".jstree") || obj === -1) { return -1; }
|
608
|
+
$obj = $obj.closest("li", this.get_container());
|
609
|
+
return $obj.length ? $obj : false;
|
610
|
+
},
|
611
|
+
/*
|
612
|
+
Function: get_next
|
613
|
+
Get the next sibling of a node
|
614
|
+
|
615
|
+
Parameters:
|
616
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc.
|
617
|
+
strict - *boolean* if set to _true_ jstree will only return immediate siblings, otherwise, if _obj_ is the last child of its parent, the parent's next sibling is returned.
|
618
|
+
|
619
|
+
Returns:
|
620
|
+
jquery collection - node was found, the collection contains the LI node
|
621
|
+
-1 - the tree container was referenced
|
622
|
+
false - node was not found, or failure (obj is not part of a tree, or does not exists in the DOM)
|
623
|
+
*/
|
624
|
+
get_next : function (obj, strict) {
|
625
|
+
obj = this.get_node(obj);
|
626
|
+
if(obj === -1) { return this.get_container_ul().children("li:eq(0)"); }
|
627
|
+
if(!obj || !obj.length) { return false; }
|
628
|
+
if(strict) { return (obj.nextAll("li").size() > 0) ? obj.nextAll("li:eq(0)") : false; }
|
629
|
+
if(obj.hasClass("jstree-open")) { return obj.find("li:eq(0)"); }
|
630
|
+
else if(obj.nextAll("li").size() > 0) { return obj.nextAll("li:eq(0)"); }
|
631
|
+
else { return obj.parentsUntil(".jstree","li").next("li").eq(0); }
|
632
|
+
},
|
633
|
+
/*
|
634
|
+
Function: get_prev
|
635
|
+
Get the previous sibling of a node
|
636
|
+
|
637
|
+
Parameters:
|
638
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc.
|
639
|
+
strict - *boolean* if set to _true_ jstree will only return immediate siblings, otherwise, if _obj_ is the first child of its parent, the parent's previous sibling is returned.
|
640
|
+
|
641
|
+
Returns:
|
642
|
+
jquery collection - node was found, the collection contains the LI node
|
643
|
+
-1 - the tree container was referenced
|
644
|
+
false - node was not found, or failure (obj is not part of a tree, or does not exists in the DOM)
|
645
|
+
*/
|
646
|
+
get_prev : function (obj, strict) {
|
647
|
+
obj = this.get_node(obj);
|
648
|
+
if(obj === -1) { return this.get_container().find("> ul > li:last-child"); }
|
649
|
+
if(!obj || !obj.length) { return false; }
|
650
|
+
if(strict) { return (obj.prevAll("li").length > 0) ? obj.prevAll("li:eq(0)") : false; }
|
651
|
+
if(obj.prev("li").length) {
|
652
|
+
obj = obj.prev("li").eq(0);
|
653
|
+
while(obj.hasClass("jstree-open")) { obj = obj.children("ul:eq(0)").children("li:last"); }
|
654
|
+
return obj;
|
655
|
+
}
|
656
|
+
else { var o = obj.parentsUntil(".jstree","li:eq(0)"); return o.length ? o : false; }
|
657
|
+
},
|
658
|
+
/*
|
659
|
+
Function: get_parent
|
660
|
+
Get the parent of a node
|
661
|
+
|
662
|
+
Parameters:
|
663
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc.
|
664
|
+
|
665
|
+
Returns:
|
666
|
+
jquery collection - node was found, the collection contains the LI node
|
667
|
+
-1 - when _obj_ was a root node
|
668
|
+
false - on failure (obj is not part of a tree, or does not exists in the DOM)
|
669
|
+
*/
|
670
|
+
get_parent : function (obj) {
|
671
|
+
obj = this.get_node(obj);
|
672
|
+
if(obj === -1 || !obj || !obj.length) { return false; }
|
673
|
+
var o = obj.parentsUntil(".jstree", "li:eq(0)");
|
674
|
+
return o.length ? o : -1;
|
675
|
+
},
|
676
|
+
/*
|
677
|
+
Function: get_children
|
678
|
+
Get all the children of a node
|
679
|
+
|
680
|
+
Parameters:
|
681
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc. If _-1_ is used all root nodes are returned.
|
682
|
+
|
683
|
+
Returns:
|
684
|
+
jquery collection - node was found, the collection contains the LI nodes of all immediate children
|
685
|
+
false - on failure (obj is not part of a tree, or does not exists in the DOM)
|
686
|
+
*/
|
687
|
+
get_children : function (obj) {
|
688
|
+
obj = this.get_node(obj);
|
689
|
+
if(obj === -1) { return this.get_container_ul().children("li"); }
|
690
|
+
if(!obj || !obj.length) { return false; }
|
691
|
+
return obj.find("> ul > li");
|
692
|
+
},
|
693
|
+
/*
|
694
|
+
Function: is_parent
|
695
|
+
Check if a node is a parent.
|
696
|
+
|
697
|
+
Parameters:
|
698
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc.
|
699
|
+
|
700
|
+
Returns:
|
701
|
+
true - _obj_ has children or is closed (will be loaded)
|
702
|
+
false - _obj_ is not a valid node or has no children (leaf node)
|
703
|
+
*/
|
704
|
+
is_parent : function (obj) { obj = this.get_node(obj); return obj && obj !== -1 && (obj.find("> ul > li:eq(0)").length || obj.hasClass("jstree-closed")); },
|
705
|
+
/*
|
706
|
+
Function: is_loaded
|
707
|
+
Check if a node is loaded.
|
708
|
+
|
709
|
+
Parameters:
|
710
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc.
|
711
|
+
|
712
|
+
Returns:
|
713
|
+
true - _obj_ has children or is leaf
|
714
|
+
false - _obj_ is currently loading or is not a leaf, but has no children
|
715
|
+
*/
|
716
|
+
is_loaded : function (obj) { obj = this.get_node(obj); return obj && ( (obj === -1 && !this.get_container().find("> ul > li.jstree-loading").length) || ( obj !== -1 && !obj.hasClass('jstree-loading') && (obj.find('> ul > li').length || obj.hasClass('jstree-leaf')) ) ); },
|
717
|
+
/*
|
718
|
+
Function: is_loading
|
719
|
+
Check if a node is currently loading.
|
720
|
+
|
721
|
+
Parameters:
|
722
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc.
|
723
|
+
|
724
|
+
Returns:
|
725
|
+
true - _obj_ is currently loading
|
726
|
+
false - _obj_ is not currently loading
|
727
|
+
*/
|
728
|
+
is_loading : function (obj) { obj = this.get_node(obj); return obj && ( (obj === -1 && this.get_container().find("> ul > li.jstree-loading").length) || (obj !== -1 && obj.hasClass("jstree-loading")) ); },
|
729
|
+
/*
|
730
|
+
Function: is_open
|
731
|
+
Check if a node is currently open.
|
732
|
+
|
733
|
+
Parameters:
|
734
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc.
|
735
|
+
|
736
|
+
Returns:
|
737
|
+
true - _obj_ is currently open
|
738
|
+
false - _obj_ is not currently open
|
739
|
+
*/
|
740
|
+
is_open : function (obj) { obj = this.get_node(obj); return obj && obj !== -1 && obj.hasClass("jstree-open"); },
|
741
|
+
/*
|
742
|
+
Function: is_closed
|
743
|
+
Check if a node is currently closed.
|
744
|
+
|
745
|
+
Parameters:
|
746
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc.
|
747
|
+
|
748
|
+
Returns:
|
749
|
+
true - _obj_ is currently closed
|
750
|
+
false - _obj_ is not currently closed
|
751
|
+
*/
|
752
|
+
is_closed : function (obj) { obj = this.get_node(obj); return obj && obj !== -1 && obj.hasClass("jstree-closed"); },
|
753
|
+
/*
|
754
|
+
Function: is_leaf
|
755
|
+
Check if a node is a leaf node (has no children).
|
756
|
+
|
757
|
+
Parameters:
|
758
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc.
|
759
|
+
|
760
|
+
Returns:
|
761
|
+
true - _obj_ is a leaf node
|
762
|
+
false - _obj_ is not a leaf node
|
763
|
+
*/
|
764
|
+
is_leaf : function (obj) { obj = this.get_node(obj); return obj && obj !== -1 && obj.hasClass("jstree-leaf"); },
|
765
|
+
/*
|
766
|
+
Function: load_node
|
767
|
+
Load the children of a node.
|
768
|
+
|
769
|
+
Parameters:
|
770
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc. Use -1 to load the root nodes.
|
771
|
+
callback - a function to be executed in the tree's scope. Receives two arguments: _obj_ (the same node used to call load_node), _status_ (a boolean indicating if the node was loaded successfully.
|
772
|
+
|
773
|
+
Returns:
|
774
|
+
true - _obj_ is a valid node and will try loading it
|
775
|
+
false - _obj_ is not a valid node
|
776
|
+
|
777
|
+
Triggers:
|
778
|
+
<load_node>
|
779
|
+
|
780
|
+
See also:
|
781
|
+
<_load_node>
|
782
|
+
|
783
|
+
Event: load_node
|
784
|
+
This event is triggered in the *jstree* namespace when a node is loaded (succesfully or not).
|
785
|
+
|
786
|
+
Parameters:
|
787
|
+
data.inst - the instance
|
788
|
+
data.args - *array* the arguments passed to the function
|
789
|
+
data.plugin - *string* the function's plugin (here it will be _"core"_ but if the function is extended it may be something else).
|
790
|
+
data.rslt - *object* which contains two keys _obj_ (the loaded node) and _status_ - whether the node was loaded successfully.
|
791
|
+
|
792
|
+
Example:
|
793
|
+
> $("div").bind("load_node.jstree", function (e, data) { if(data.rslt.status) { data.inst.open_node(data.rslt.obj); } });
|
794
|
+
*/
|
795
|
+
load_node : function (obj, callback) {
|
796
|
+
obj = this.get_node(obj);
|
797
|
+
if(!obj) { callback.call(this, obj, false); return false; }
|
798
|
+
// if(this.is_loading(obj)) { return true; }
|
799
|
+
if(obj !== -1) { obj.addClass("jstree-loading"); }
|
800
|
+
this._load_node(obj, $.proxy(function (status) {
|
801
|
+
if(obj !== -1) { obj.removeClass("jstree-loading"); }
|
802
|
+
this.__callback({ "obj" : obj, "status" : status });
|
803
|
+
if(callback) { callback.call(this, obj, status); }
|
804
|
+
}, this));
|
805
|
+
return true;
|
806
|
+
},
|
807
|
+
/*
|
808
|
+
Function: _load_node
|
809
|
+
Load the children of a node, but as opposed to <load_node> does not change any visual properties or trigger events. This function is used in <load_node> internally. The idea is for data source plugins to overwrite this function.
|
810
|
+
This implementation (from the *core*) only uses markup found in the tree container, and does not load async.
|
811
|
+
|
812
|
+
Parameters:
|
813
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc. Use -1 to load the root nodes.
|
814
|
+
callback - a function to be executed in the tree's scope. Receives one argument: _status_ (a boolean indicating if the node was loaded successfully).
|
815
|
+
*/
|
816
|
+
_load_node : function (obj, callback) {
|
817
|
+
// if using async - empty the node first
|
818
|
+
if(obj === -1) {
|
819
|
+
this.get_container_ul().empty().append(this.data.core.original_container_html.clone(true));
|
820
|
+
}
|
821
|
+
callback.call(null, true);
|
822
|
+
},
|
823
|
+
/*
|
824
|
+
Function: open_node
|
825
|
+
Open a node so that its children are visible. If the node is not loaded try loading it first.
|
826
|
+
|
827
|
+
Parameters:
|
828
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc.
|
829
|
+
callback - a function to be executed in the tree's scope. Receives two arguments: _obj_ (the node being opened) and _status_ (a boolean indicating if the node was opened successfully).
|
830
|
+
animation - the duration in miliseconds of the slideDown animation. If not supplied the jQuery default is used. Please note that on IE6 a _0_ is enforced here due to performance issues.
|
831
|
+
|
832
|
+
Triggers:
|
833
|
+
<open_node>, <__after_open>
|
834
|
+
|
835
|
+
Event: open_node
|
836
|
+
This event is triggered in the *jstree* namespace when a node is successfully opened (but if animation is used this event is triggered BEFORE the animation completes). See <__after_open>.
|
837
|
+
|
838
|
+
Parameters:
|
839
|
+
data.inst - the instance
|
840
|
+
data.args - *array* the arguments passed to the function
|
841
|
+
data.plugin - *string* the function's plugin (here it will be _"core"_ but if the function is extended it may be something else).
|
842
|
+
data.rslt - *object* which contains a single key: _obj_ (the opened node).
|
843
|
+
|
844
|
+
Example:
|
845
|
+
> $("div").bind("open_node.jstree", function (e, data) {
|
846
|
+
> data.rslt.obj.find('> ul > .jstree-closed').each(function () {
|
847
|
+
> data.inst.open_node(this);
|
848
|
+
> }
|
849
|
+
> });
|
850
|
+
|
851
|
+
Event: __after_open
|
852
|
+
This event is triggered in the *jstree* namespace when a node is successfully opened AFTER the animation completes). See <open_node>.
|
853
|
+
|
854
|
+
Parameters:
|
855
|
+
data.inst - the instance
|
856
|
+
data.rslt - *object* which contains a single key: _obj_ (the opened node).
|
857
|
+
|
858
|
+
Example:
|
859
|
+
> $("div").bind("__after_open.jstree", function (e, data) {
|
860
|
+
> data.rslt.obj.find('> ul > .jstree-closed').each(function () {
|
861
|
+
> data.inst.open_node(this);
|
862
|
+
> }
|
863
|
+
> });
|
864
|
+
*/
|
865
|
+
open_node : function (obj, callback, animation) {
|
866
|
+
obj = this.get_node(obj);
|
867
|
+
if(obj === -1 || !obj || !obj.length) { return false; }
|
868
|
+
if(!this.is_closed(obj)) { if(callback) { callback.call(this, obj, false); } return false; }
|
869
|
+
if(!this.is_loaded(obj)) { // TODO: is_loading?
|
870
|
+
this.load_node(obj, function (o, ok) {
|
871
|
+
return ok ? this.open_node(o, callback, animation) : callback ? callback.call(this, o, false) : false;
|
872
|
+
});
|
873
|
+
}
|
874
|
+
else {
|
875
|
+
var t = this;
|
876
|
+
obj
|
877
|
+
.children("ul").css("display","none").end()
|
878
|
+
.removeClass("jstree-closed").addClass("jstree-open")
|
879
|
+
// .children("ins").text("-").end()
|
880
|
+
.children("ul").stop(true, true).slideDown( ($.jstree.IS_IE6 ? 0 : animation), function () {
|
881
|
+
this.style.display = "";
|
882
|
+
t.__trigger("__after_open", { "rslt" : { "obj" : obj } });
|
883
|
+
});
|
884
|
+
if(callback) { callback.call(this, obj, true); }
|
885
|
+
this.__callback({ "obj" : obj });
|
886
|
+
}
|
887
|
+
},
|
888
|
+
/*
|
889
|
+
Function: close_node
|
890
|
+
Close a node so that its children are not visible.
|
891
|
+
|
892
|
+
Parameters:
|
893
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc.
|
894
|
+
animation - the duration in miliseconds of the slideDown animation. If not supplied the jQuery default is used. Please note that on IE6 a _0_ is enforced here due to performance issues.
|
895
|
+
|
896
|
+
Triggers:
|
897
|
+
<close_node>, <__after_close>
|
898
|
+
|
899
|
+
Event: close_node
|
900
|
+
This event is triggered in the *jstree* namespace when a node is closed (but if animation is used this event is triggered BEFORE the animation completes). See <__after_close>.
|
901
|
+
|
902
|
+
Parameters:
|
903
|
+
data.inst - the instance
|
904
|
+
data.args - *array* the arguments passed to the function
|
905
|
+
data.plugin - *string* the function's plugin (here it will be _"core"_ but if the function is extended it may be something else).
|
906
|
+
data.rslt - *object* which contains a single key: _obj_ (the closed node).
|
907
|
+
|
908
|
+
Example:
|
909
|
+
> $("div").bind("close_node.jstree", function (e, data) {
|
910
|
+
> data.rslt.obj.children('ul').remove();
|
911
|
+
> });
|
912
|
+
|
913
|
+
Event: __after_close
|
914
|
+
This event is triggered in the *jstree* namespace when a node is closed AFTER the animation completes). See <close_node>.
|
915
|
+
|
916
|
+
Parameters:
|
917
|
+
data.inst - the instance
|
918
|
+
data.rslt - *object* which contains a single key: _obj_ (the opened node).
|
919
|
+
|
920
|
+
Example:
|
921
|
+
> $("div").bind("__after_close.jstree", function (e, data) {
|
922
|
+
> data.rslt.obj.children('ul').remove();
|
923
|
+
> });
|
924
|
+
*/
|
925
|
+
close_node : function (obj, animation) {
|
926
|
+
obj = this.get_node(obj);
|
927
|
+
if(!obj || !obj.length || !this.is_open(obj)) { return false; }
|
928
|
+
var t = this;
|
929
|
+
obj
|
930
|
+
.children("ul").attr("style","display:block !important").end()
|
931
|
+
.removeClass("jstree-open").addClass("jstree-closed")
|
932
|
+
// .children("ins").text("+").end()
|
933
|
+
.children("ul").stop(true, true).slideUp( ($.jstree.IS_IE6 ? 0 : animation), function () {
|
934
|
+
this.style.display = "";
|
935
|
+
t.__trigger("__after_close", { "rslt" : { "obj" : obj } });
|
936
|
+
});
|
937
|
+
this.__callback({ "obj" : obj });
|
938
|
+
},
|
939
|
+
/*
|
940
|
+
Function: toggle_node
|
941
|
+
If a node is closed - open it, if it is open - close it.
|
942
|
+
|
943
|
+
Parameters:
|
944
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc.
|
945
|
+
*/
|
946
|
+
toggle_node : function (obj) {
|
947
|
+
if(this.is_closed(obj)) { return this.open_node(obj); }
|
948
|
+
if(this.is_open(obj)) { return this.close_node(obj); }
|
949
|
+
},
|
950
|
+
/*
|
951
|
+
Function: open_all
|
952
|
+
Open all nodes from a certain node down.
|
953
|
+
|
954
|
+
Parameters:
|
955
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc. If _-1_ is used or is omitted all nodes in the tree are opened.
|
956
|
+
animation - the duration of the slideDown animation when opening the nodes. If not set _0_ is enforced for performance issues.
|
957
|
+
original_obj - used internally to keep track of the recursion - do not set manually!
|
958
|
+
|
959
|
+
Triggers:
|
960
|
+
<open_all>
|
961
|
+
|
962
|
+
Event: open_all
|
963
|
+
This event is triggered in the *jstree* namespace when an open_all call completes.
|
964
|
+
|
965
|
+
Parameters:
|
966
|
+
data.inst - the instance
|
967
|
+
data.args - *array* the arguments passed to the function
|
968
|
+
data.plugin - *string* the function's plugin (here it will be _"core"_ but if the function is extended it may be something else).
|
969
|
+
data.rslt - *object* which contains a single key: _obj_ (the node used in the call).
|
970
|
+
|
971
|
+
Example:
|
972
|
+
> $("div").bind("open_all.jstree", function (e, data) {
|
973
|
+
> alert('DONE');
|
974
|
+
> });
|
975
|
+
*/
|
976
|
+
open_all : function (obj, animation, original_obj) {
|
977
|
+
obj = obj ? this.get_node(obj) : -1;
|
978
|
+
obj = !obj || obj === -1 ? this.get_container_ul() : obj;
|
979
|
+
original_obj = original_obj || obj;
|
980
|
+
var _this = this;
|
981
|
+
obj = this.is_closed(obj) ? obj.find('li.jstree-closed').andSelf() : obj.find('li.jstree-closed');
|
982
|
+
obj.each(function () {
|
983
|
+
_this.open_node(
|
984
|
+
this,
|
985
|
+
_this.is_loaded(this) ?
|
986
|
+
false :
|
987
|
+
function(obj) { this.open_all(obj, animation, original_obj); },
|
988
|
+
animation || 0
|
989
|
+
);
|
990
|
+
});
|
991
|
+
if(original_obj.find('li.jstree-closed').length === 0) { this.__callback({ "obj" : original_obj }); }
|
992
|
+
},
|
993
|
+
/*
|
994
|
+
Function: close_all
|
995
|
+
Close all nodes from a certain node down.
|
996
|
+
|
997
|
+
Parameters:
|
998
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc. If _-1_ is used or is omitted all nodes in the tree are closed.
|
999
|
+
animation - the duration of the slideDown animation when closing the nodes. If not set _0_ is enforced for performance issues.
|
1000
|
+
|
1001
|
+
Triggers:
|
1002
|
+
<close_all>
|
1003
|
+
|
1004
|
+
Event: close_all
|
1005
|
+
This event is triggered in the *jstree* namespace when a close_all call completes.
|
1006
|
+
|
1007
|
+
Parameters:
|
1008
|
+
data.inst - the instance
|
1009
|
+
data.args - *array* the arguments passed to the function
|
1010
|
+
data.plugin - *string* the function's plugin (here it will be _"core"_ but if the function is extended it may be something else).
|
1011
|
+
data.rslt - *object* which contains a single key: _obj_ (the node used in the call).
|
1012
|
+
|
1013
|
+
Example:
|
1014
|
+
> $("div").bind("close_all.jstree", function (e, data) {
|
1015
|
+
> alert('DONE');
|
1016
|
+
> });
|
1017
|
+
*/
|
1018
|
+
close_all : function (obj, animation) {
|
1019
|
+
obj = obj ? this._get_node(obj) : -1;
|
1020
|
+
var $obj = !obj || obj === -1 ? this.get_container_ul() : obj,
|
1021
|
+
_this = this;
|
1022
|
+
$obj = this.is_open($obj) ? $obj.find('li.jstree-open').andSelf() : $obj.find('li.jstree-open');
|
1023
|
+
$obj.each(function () { _this.close_node(this, animation || 0); });
|
1024
|
+
this.__callback({ "obj" : obj });
|
1025
|
+
},
|
1026
|
+
/*
|
1027
|
+
Function: clean_node
|
1028
|
+
This function converts inserted nodes to the required by jsTree format. It takes care of converting a simple unodreder list to the internally used markup.
|
1029
|
+
The core calls this function automatically when new data arrives (by binding to the <load_node> event).
|
1030
|
+
Each plugin may override this function to include its own source, but keep in mind to do it like that:
|
1031
|
+
> clean_node : function(obj) {
|
1032
|
+
> obj = this.__call_old();
|
1033
|
+
> obj.each(function () {
|
1034
|
+
> // do your stuff here
|
1035
|
+
> });
|
1036
|
+
> }
|
1037
|
+
|
1038
|
+
Parameters:
|
1039
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc. If _-1_ is used or is omitted all nodes in the tree are cleaned.
|
1040
|
+
|
1041
|
+
Returns:
|
1042
|
+
jQuery collection - the cleaned children of the original node.
|
1043
|
+
*/
|
1044
|
+
clean_node : function (obj) {
|
1045
|
+
// DETACH maybe inside the "load_node" function? But what about animations, etc?
|
1046
|
+
obj = this.get_node(obj);
|
1047
|
+
obj = !obj || obj === -1 ? this.get_container().find("li") : obj.find("li").andSelf();
|
1048
|
+
var _this = this;
|
1049
|
+
return obj.each(function () {
|
1050
|
+
var t = $(this),
|
1051
|
+
d = t.data("jstree"),
|
1052
|
+
s = (d && d.opened) || t.hasClass("jstree-open") ? "open" : (d && d.closed) || t.children("ul").length ? "closed" : "leaf";
|
1053
|
+
if(d && d.opened) { delete d.opened; }
|
1054
|
+
if(d && d.closed) { delete d.closed; }
|
1055
|
+
t.removeClass("jstree-open jstree-closed jstree-leaf jstree-last");
|
1056
|
+
if(!t.children("a").length) {
|
1057
|
+
// allow for text and HTML markup inside the nodes
|
1058
|
+
t.contents().filter(function() { return this.nodeType === 3 || this.tagName !== 'UL'; }).wrapAll('<a href="#"></a>');
|
1059
|
+
// TODO: make this faster
|
1060
|
+
t.children('a').html(t.children('a').html().replace(/[\s\t\n]+$/,''));
|
1061
|
+
}
|
1062
|
+
else {
|
1063
|
+
if(!$.trim(t.children('a').attr('href'))) { t.children('a').attr("href","#"); }
|
1064
|
+
}
|
1065
|
+
if(!t.children("ins.jstree-ocl").length) {
|
1066
|
+
t.prepend("<ins class='jstree-icon jstree-ocl'> </ins>");
|
1067
|
+
}
|
1068
|
+
if(t.is(":last-child")) {
|
1069
|
+
t.addClass("jstree-last");
|
1070
|
+
}
|
1071
|
+
switch(s) {
|
1072
|
+
case 'leaf':
|
1073
|
+
t.addClass('jstree-leaf');
|
1074
|
+
break;
|
1075
|
+
case 'closed':
|
1076
|
+
t.addClass('jstree-open');
|
1077
|
+
_this.close_node(t, 0);
|
1078
|
+
break;
|
1079
|
+
case 'open':
|
1080
|
+
t.addClass('jstree-closed');
|
1081
|
+
_this.open_node(t, false, 0);
|
1082
|
+
break;
|
1083
|
+
}
|
1084
|
+
});
|
1085
|
+
},
|
1086
|
+
/*
|
1087
|
+
Function: correct_node
|
1088
|
+
This function corrects the open/closed/leaf state as data changes (as the user interacts with the tree).
|
1089
|
+
The core calls this function automatically when a node is opened, deleted or moved.
|
1090
|
+
|
1091
|
+
Parameters:
|
1092
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc. If _-1_ is used or is omitted the root nodes are processed.
|
1093
|
+
|
1094
|
+
Returns:
|
1095
|
+
jQuery collection - the processed children of the original node.
|
1096
|
+
*/
|
1097
|
+
/* PROCESS SINGLE NODE (OR USE BOOLEAN single PARAM), CALL FROM CLEAN_NODE, LOSE THE EVENTS ABOVE */
|
1098
|
+
correct_node : function (obj, deep) {
|
1099
|
+
obj = this.get_node(obj);
|
1100
|
+
if(!obj || (obj === -1 && !deep)) { return false; }
|
1101
|
+
if(obj === -1) { obj = this.get_container().find('li'); }
|
1102
|
+
else { obj = deep ? obj.find('li').andSelf() : obj; }
|
1103
|
+
obj.each(function () {
|
1104
|
+
var obj = $(this);
|
1105
|
+
switch(!0) {
|
1106
|
+
case obj.hasClass("jstree-open") && !obj.find("> ul > li").length:
|
1107
|
+
obj.removeClass("jstree-open").addClass("jstree-leaf").children("ul").remove(); // children("ins").html(" ").end()
|
1108
|
+
break;
|
1109
|
+
case obj.hasClass("jstree-leaf") && !!obj.find("> ul > li").length:
|
1110
|
+
obj.removeClass("jstree-leaf").addClass("jstree-closed"); //.children("ins").html("+");
|
1111
|
+
break;
|
1112
|
+
}
|
1113
|
+
obj[obj.is(":last-child") ? 'addClass' : 'removeClass']("jstree-last");
|
1114
|
+
});
|
1115
|
+
return obj;
|
1116
|
+
},
|
1117
|
+
/*
|
1118
|
+
Function: scroll_to_node
|
1119
|
+
This function scrolls the container to the desired node (if needed).
|
1120
|
+
|
1121
|
+
Parameters:
|
1122
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc.
|
1123
|
+
*/
|
1124
|
+
scroll_to_node : function (obj) {
|
1125
|
+
var c = this.get_container()[0], t;
|
1126
|
+
if(c.scrollHeight > c.offsetHeight) {
|
1127
|
+
obj = this.get_node(obj);
|
1128
|
+
if(!obj || obj === -1 || !obj.length || !obj.is(":visible")) { return; }
|
1129
|
+
t = obj.offset().top - this.get_container().offset().top;
|
1130
|
+
if(t < 0) {
|
1131
|
+
c.scrollTop = c.scrollTop + t - 1;
|
1132
|
+
}
|
1133
|
+
if(t + this.data.core.li_height + (c.scrollWidth > c.offsetWidth ? $.jstree.SCROLLBAR_WIDTH : 0) > c.offsetHeight) {
|
1134
|
+
c.scrollTop = c.scrollTop + (t - c.offsetHeight + this.data.core.li_height + 1 + (c.scrollWidth > c.offsetWidth ? $.jstree.SCROLLBAR_WIDTH : 0));
|
1135
|
+
}
|
1136
|
+
}
|
1137
|
+
},
|
1138
|
+
/*
|
1139
|
+
Function: get_state
|
1140
|
+
This function returns the current state of the tree (as collected from all active plugins).
|
1141
|
+
Plugin authors: pay special attention to the way this function is extended for new plugins. In your plugin code write:
|
1142
|
+
> get_state : function () {
|
1143
|
+
> var state = this.__call_old();
|
1144
|
+
> state.your-plugin-name = <some-value-you-collect>;
|
1145
|
+
> return state;
|
1146
|
+
> }
|
1147
|
+
|
1148
|
+
Returns:
|
1149
|
+
object - the current state of the instance
|
1150
|
+
*/
|
1151
|
+
get_state : function () { // TODO: scroll position, theme
|
1152
|
+
var state = { 'open' : [], 'scroll' : { 'left' : this.get_container().scrollLeft(), 'top' : this.get_container().scrollTop() } };
|
1153
|
+
this.get_container_ul().find('.jstree-open').each(function () { if(this.id) { state.open.push(this.id); } });
|
1154
|
+
return state;
|
1155
|
+
},
|
1156
|
+
/*
|
1157
|
+
Function: set_state
|
1158
|
+
This function returns sets the state of the tree.
|
1159
|
+
Plugin authors: pay special attention to the way this function is extended for new plugins. In your plugin code write:
|
1160
|
+
> set_state : function (state, callback) {
|
1161
|
+
> if(this.__call_old()) {
|
1162
|
+
> if(state.your-plugin-name) {
|
1163
|
+
>
|
1164
|
+
> // restore using `state.your-plugin-name`
|
1165
|
+
> // if you need some async activity so that you return to this bit of code
|
1166
|
+
> // do not delete state.your-plugin-name and return false (see core's function for example)
|
1167
|
+
>
|
1168
|
+
> delete state.your-plugin-name;
|
1169
|
+
> this.set_state(state, callback);
|
1170
|
+
> return false;
|
1171
|
+
> }
|
1172
|
+
> return true;
|
1173
|
+
> }
|
1174
|
+
> return false;
|
1175
|
+
> }
|
1176
|
+
|
1177
|
+
Parameters:
|
1178
|
+
state - *object* the state to restore to
|
1179
|
+
callback - *function* this will be executed in the instance's scope once restoring is done
|
1180
|
+
|
1181
|
+
Returns:
|
1182
|
+
boolean - the return value is used to determine the phase of restoration
|
1183
|
+
|
1184
|
+
Triggers:
|
1185
|
+
<set_state>
|
1186
|
+
|
1187
|
+
Event: set_state
|
1188
|
+
This event is triggered in the *jstree* namespace when a set_state call completes.
|
1189
|
+
|
1190
|
+
Parameters:
|
1191
|
+
data.inst - the instance
|
1192
|
+
data.args - *array* the arguments passed to the function
|
1193
|
+
data.plugin - *string* the function's plugin (here it will be _"core"_ but if the function is extended it may be something else)
|
1194
|
+
*/
|
1195
|
+
set_state : function (state, callback) {
|
1196
|
+
if(state) {
|
1197
|
+
if($.isArray(state.open)) {
|
1198
|
+
var res = true,
|
1199
|
+
t = this;
|
1200
|
+
//this.close_all();
|
1201
|
+
$.each(state.open.concat([]), function (i, v) {
|
1202
|
+
v = document.getElementById(v);
|
1203
|
+
if(v) {
|
1204
|
+
if(t.is_loaded(v)) {
|
1205
|
+
if(t.is_closed(v)) {
|
1206
|
+
t.open_node(v, false, 0);
|
1207
|
+
}
|
1208
|
+
$.vakata.array_remove(state.open, i);
|
1209
|
+
}
|
1210
|
+
else {
|
1211
|
+
if(!t.is_loading(v)) {
|
1212
|
+
t.open_node(v, $.proxy(function () { this.set_state(state); }, t), 0);
|
1213
|
+
}
|
1214
|
+
// there will be some async activity - so wait for it
|
1215
|
+
res = false;
|
1216
|
+
}
|
1217
|
+
}
|
1218
|
+
});
|
1219
|
+
if(res) {
|
1220
|
+
delete state.open;
|
1221
|
+
this.set_state(state, callback);
|
1222
|
+
}
|
1223
|
+
return false;
|
1224
|
+
}
|
1225
|
+
if(state.scroll) {
|
1226
|
+
if(state.scroll && typeof state.scroll.left !== 'undefined') {
|
1227
|
+
this.get_container().scrollLeft(state.scroll.left);
|
1228
|
+
}
|
1229
|
+
if(state.scroll && typeof state.scroll.top !== 'undefined') {
|
1230
|
+
this.get_container().scrollTop(state.scroll.top);
|
1231
|
+
}
|
1232
|
+
delete state.scroll;
|
1233
|
+
delete state.open;
|
1234
|
+
this.set_state(state, callback);
|
1235
|
+
return false;
|
1236
|
+
}
|
1237
|
+
if($.isEmptyObject(state)) {
|
1238
|
+
if(callback) { callback.call(this); }
|
1239
|
+
this.__callback();
|
1240
|
+
return false;
|
1241
|
+
}
|
1242
|
+
return true;
|
1243
|
+
}
|
1244
|
+
return false;
|
1245
|
+
},
|
1246
|
+
/*
|
1247
|
+
Function: refresh
|
1248
|
+
This function saves the current state, reloads the complete tree and returns it to the saved state.
|
1249
|
+
|
1250
|
+
Triggers:
|
1251
|
+
<refresh>
|
1252
|
+
|
1253
|
+
Event: refresh
|
1254
|
+
This event is triggered in the *jstree* namespace when a refresh call completes.
|
1255
|
+
|
1256
|
+
Parameters:
|
1257
|
+
data.inst - the instance
|
1258
|
+
*/
|
1259
|
+
refresh : function () {
|
1260
|
+
this.data.core.state = this.get_state();
|
1261
|
+
this.load_node(-1, function (o, s) {
|
1262
|
+
if(s) {
|
1263
|
+
this.set_state($.extend(true, {}, this.data.core.state), function () { this.__trigger('refresh'); });
|
1264
|
+
}
|
1265
|
+
this.data.core.state = null;
|
1266
|
+
});
|
1267
|
+
},
|
1268
|
+
/*
|
1269
|
+
Function: get_text
|
1270
|
+
This function returns the title of the node.
|
1271
|
+
|
1272
|
+
Parameters:
|
1273
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc.
|
1274
|
+
remove_html - *boolean* set to _true_ to return plain text instead of HTML
|
1275
|
+
|
1276
|
+
Returns:
|
1277
|
+
string - the title of the node, specified by _obj_
|
1278
|
+
*/
|
1279
|
+
get_text : function (obj, remove_html) {
|
1280
|
+
obj = this.get_node(obj);
|
1281
|
+
if(!obj || obj === -1 || !obj.length) { return false; }
|
1282
|
+
obj = obj.children("a:eq(0)").clone();
|
1283
|
+
obj.children(".jstree-icon").remove();
|
1284
|
+
return obj[ remove_html ? 'text' : 'html' ]();
|
1285
|
+
},
|
1286
|
+
/*
|
1287
|
+
Function: set_text
|
1288
|
+
This function sets the title of the node. This is a low-level function, you'd be better off using <rename>.
|
1289
|
+
|
1290
|
+
Parameters:
|
1291
|
+
obj - *mixed* this is used as a jquery selector - can be jQuery object, DOM node, string, etc.
|
1292
|
+
val - *string* the new title of the node (can be HTMl too)
|
1293
|
+
|
1294
|
+
Returns:
|
1295
|
+
boolean - was the rename successfull
|
1296
|
+
|
1297
|
+
Triggers:
|
1298
|
+
<set_text>
|
1299
|
+
|
1300
|
+
Event: set_text
|
1301
|
+
This event is triggered in the *jstree* namespace when a set_text call completes.
|
1302
|
+
|
1303
|
+
Parameters:
|
1304
|
+
data.inst - the instance
|
1305
|
+
data.args - *array* the arguments passed to the function
|
1306
|
+
data.plugin - *string* the function's plugin (here it will be _"core"_ but if the function is extended it may be something else)
|
1307
|
+
data.rslt - *object* which contains a two keys: _obj_ (the node) and _val_ (the new title).
|
1308
|
+
|
1309
|
+
Example:
|
1310
|
+
> $("div").bind("set_text.jstree", function (e, data) {
|
1311
|
+
> alert("Renamed to: " + data.rslt.val);
|
1312
|
+
> });
|
1313
|
+
*/
|
1314
|
+
set_text : function (obj, val) {
|
1315
|
+
obj = this.get_node(obj);
|
1316
|
+
if(!obj || obj === -1 || !obj.length) { return false; }
|
1317
|
+
obj = obj.children("a:eq(0)");
|
1318
|
+
var tmp = obj.children("INS").clone();
|
1319
|
+
obj.html(val).prepend(tmp);
|
1320
|
+
this.__callback({ "obj" : obj, "text" : val });
|
1321
|
+
return true;
|
1322
|
+
},
|
1323
|
+
/*
|
1324
|
+
Function: parse_json
|
1325
|
+
This function returns a jQuery node after parsing a JSON object (a LI node for single elements or an UL node for multiple). This function will use the default title from <jstree.config.core.strings> if none is specified.
|
1326
|
+
|
1327
|
+
Parameters:
|
1328
|
+
node - *mixed* the input to parse
|
1329
|
+
> // can be a string
|
1330
|
+
> "The title of the parsed node"
|
1331
|
+
> // array of strings
|
1332
|
+
> [ "Node 1", "Node 2" ]
|
1333
|
+
> // an object
|
1334
|
+
> { "title" : "The title of the parsed node" }
|
1335
|
+
> // you can manipulate the output
|
1336
|
+
> { "title" : "The title of the parsed node", "li_attr" : { "id" : "id_for_li" }, "a_attr" : { "href" : "http://jstree.com" } }
|
1337
|
+
> // you can supply metadata, which you can later access using $(the_li_node).data()
|
1338
|
+
> { "title" : "The title of the parsed node", "data" : { <some-values-here> } }
|
1339
|
+
> // you can supply children (they can be objects too)
|
1340
|
+
> { "title" : "The title of the parsed node", "children" : [ "Node 1", { "title" : "Node 2" } ] }
|
1341
|
+
|
1342
|
+
Returns:
|
1343
|
+
jQuery - the LI (or UL) node which was produced from the JSON
|
1344
|
+
*/
|
1345
|
+
parse_json : function (node) {
|
1346
|
+
var li, a, ul, t;
|
1347
|
+
if($.isArray(node)) {
|
1348
|
+
ul = $("<ul />");
|
1349
|
+
t = this;
|
1350
|
+
$.each(node, function (i, v) {
|
1351
|
+
ul.append(t.parse_json(v));
|
1352
|
+
});
|
1353
|
+
return ul;
|
1354
|
+
}
|
1355
|
+
if(typeof node === "undefined") { node = {}; }
|
1356
|
+
if(typeof node === "string") { node = { "title" : node }; }
|
1357
|
+
if(!node.li_attr) { node.li_attr = {}; }
|
1358
|
+
if(!node.a_attr) { node.a_attr = {}; }
|
1359
|
+
if(!node.a_attr.href) { node.a_attr.href = '#'; }
|
1360
|
+
if(!node.title) { node.title = this._get_string("New node"); }
|
1361
|
+
|
1362
|
+
li = $("<li />").attr(node.li_attr);
|
1363
|
+
a = $("<a />").attr(node.a_attr).html(node.title);
|
1364
|
+
ul = $("<ul />");
|
1365
|
+
if(node.data && !$.isEmptyObject(node.data)) { li.data(node.data); }
|
1366
|
+
if(
|
1367
|
+
node.children === true ||
|
1368
|
+
$.isArray(node.children) ||
|
1369
|
+
(li.data('jstree') && $.isArray(li.data('jstree').children))
|
1370
|
+
) {
|
1371
|
+
if(!li.data('jstree')) {
|
1372
|
+
li.data('jstree', {});
|
1373
|
+
}
|
1374
|
+
li.data('jstree').closed = true;
|
1375
|
+
}
|
1376
|
+
li.append(a);
|
1377
|
+
if($.isArray(node.children)) {
|
1378
|
+
$.each(node.children, $.proxy(function (i, n) {
|
1379
|
+
ul.append(this.parse_json(n));
|
1380
|
+
}, this));
|
1381
|
+
li.append(ul);
|
1382
|
+
}
|
1383
|
+
return li;
|
1384
|
+
},
|
1385
|
+
/*
|
1386
|
+
Function: get_json
|
1387
|
+
This function returns the whole tree (or a single node) in JSON format.
|
1388
|
+
Each plugin may override this function to include its own source, but keep in mind to do it like that:
|
1389
|
+
> get_json : function(obj, is_callback) {
|
1390
|
+
> var r = this.__call_old();
|
1391
|
+
> if(is_callback) {
|
1392
|
+
> if(<some-condition>) { r.data.jstree.<some-key> = <some-value-this-plugin-will-process>; }
|
1393
|
+
> }
|
1394
|
+
> return r;
|
1395
|
+
> }
|
1396
|
+
|
1397
|
+
Parameters:
|
1398
|
+
obj - *mixed* the input to parse
|
1399
|
+
is_callback - do not modify this, jstree uses this parameter to keep track of the recursion
|
1400
|
+
|
1401
|
+
Returns:
|
1402
|
+
Array - an array consisting of objects (one for each node)
|
1403
|
+
*/
|
1404
|
+
get_json : function (obj, is_callback) {
|
1405
|
+
obj = typeof obj !== 'undefined' ? this.get_node(obj) : false;
|
1406
|
+
if(!is_callback) {
|
1407
|
+
if(!obj || obj === -1) { obj = this.get_container_ul().children("li"); }
|
1408
|
+
}
|
1409
|
+
var r, t, li_attr = {}, a_attr = {}, tmp = {};
|
1410
|
+
if(!obj || !obj.length) { return false; }
|
1411
|
+
if(obj.length > 1 || !is_callback) {
|
1412
|
+
r = [];
|
1413
|
+
t = this;
|
1414
|
+
obj.each(function () {
|
1415
|
+
r.push(t.get_json($(this), true));
|
1416
|
+
});
|
1417
|
+
return r;
|
1418
|
+
}
|
1419
|
+
tmp = $.vakata.attributes(obj, true);
|
1420
|
+
$.each(tmp, function (i, v) {
|
1421
|
+
if(i === 'id') { li_attr[i] = v; return true; }
|
1422
|
+
v = $.trim(v.replace(/\bjstree[^ ]*/ig,'').replace(/\s+$/ig," "));
|
1423
|
+
if(v.length) { li_attr[i] = v; }
|
1424
|
+
});
|
1425
|
+
tmp = $.vakata.attributes(obj.children('a'), true);
|
1426
|
+
$.each(tmp, function (i, v) {
|
1427
|
+
if(i === 'id') { a_attr[i] = v; return true; }
|
1428
|
+
v = $.trim(v.replace(/\bjstree[^ ]*/ig,'').replace(/\s+$/ig," "));
|
1429
|
+
if(v.length) { a_attr[i] = v; }
|
1430
|
+
});
|
1431
|
+
r = {
|
1432
|
+
'title' : this.get_text(obj),
|
1433
|
+
'data' : $.extend(true, {}, obj.data() || {}),
|
1434
|
+
'children' : false,
|
1435
|
+
'li_attr' : li_attr,
|
1436
|
+
'a_attr' : a_attr
|
1437
|
+
};
|
1438
|
+
|
1439
|
+
if(!r.data.jstree) { r.data.jstree = {}; }
|
1440
|
+
if(this.is_open(obj)) { r.data.jstree.opened = true; }
|
1441
|
+
if(this.is_closed(obj)) { r.data.jstree.closed = true; }
|
1442
|
+
|
1443
|
+
obj = obj.find('> ul > li');
|
1444
|
+
if(obj.length) {
|
1445
|
+
r.children = [];
|
1446
|
+
t = this;
|
1447
|
+
obj.each(function () {
|
1448
|
+
r.children.push(t.get_json($(this), true));
|
1449
|
+
});
|
1450
|
+
}
|
1451
|
+
return r;
|
1452
|
+
},
|
1453
|
+
/*
|
1454
|
+
Function: create_node
|
1455
|
+
This function creates a new node.
|
1456
|
+
|
1457
|
+
Parameters:
|
1458
|
+
parent - *mixed* the parent for the newly created node. This is used as a jquery selector, can be jQuery object, DOM node, string, etc. Use -1 to create a new root node.
|
1459
|
+
node - *mixed* the input to parse, check <parse_json> for description
|
1460
|
+
position - *mixed* where to create the new node. Can be one of "before", "after", "first", "last", "inside" or a numerical index.
|
1461
|
+
callback - optional function to be executed once the node is created
|
1462
|
+
is_loaded - used internally when a node needs to be loaded - do not pass this
|
1463
|
+
|
1464
|
+
Returns:
|
1465
|
+
jQuery - the LI node which was produced from the JSON (may return _undefined_ if the parent node is not yet loaded, but will create the node)
|
1466
|
+
|
1467
|
+
Triggers:
|
1468
|
+
<create_node>
|
1469
|
+
|
1470
|
+
Event: create_node
|
1471
|
+
This event is triggered in the *jstree* namespace when a new node is created.
|
1472
|
+
|
1473
|
+
Parameters:
|
1474
|
+
data.inst - the instance
|
1475
|
+
data.args - *array* the arguments passed to the function
|
1476
|
+
data.plugin - *string* the function's plugin (here it will be _"core"_ but if the function is extended it may be something else)
|
1477
|
+
data.rslt - *object* which contains a three keys: _obj_ (the node), _parent_ (the parent) and _position_ which is the numerical index.
|
1478
|
+
|
1479
|
+
Example:
|
1480
|
+
> $("div").bind("create_node.jstree", function (e, data) {
|
1481
|
+
> alert("Created `" + data.inst.get_text(data.rslt.obj) + "` inside `" + (data.rslt.parent === -1 ? 'the main container' : data.inst.get_text(data.rslt.parent)) + "` at index " + data.rslt.position);
|
1482
|
+
> });
|
1483
|
+
*/
|
1484
|
+
create_node : function (par, node, pos, callback, is_loaded) {
|
1485
|
+
par = this.get_node(par);
|
1486
|
+
pos = typeof pos === "undefined" ? "last" : pos;
|
1487
|
+
|
1488
|
+
if(par !== -1 && !par.length) { return false; }
|
1489
|
+
if(!pos.match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {
|
1490
|
+
return this.load_node(par, function () { this.create_node(par, node, pos, callback, true); });
|
1491
|
+
}
|
1492
|
+
|
1493
|
+
var li = this.parse_json(node),
|
1494
|
+
tmp = par === -1 ? this.get_container() : par;
|
1495
|
+
|
1496
|
+
if(par === -1) {
|
1497
|
+
if(pos === "before") { pos = "first"; }
|
1498
|
+
if(pos === "after") { pos = "last"; }
|
1499
|
+
}
|
1500
|
+
switch(pos) {
|
1501
|
+
case "before":
|
1502
|
+
pos = par.index();
|
1503
|
+
par = this.get_parent(par);
|
1504
|
+
break;
|
1505
|
+
case "after" :
|
1506
|
+
pos = par.index() + 1;
|
1507
|
+
par = this.get_parent(par);
|
1508
|
+
break;
|
1509
|
+
case "inside":
|
1510
|
+
case "first":
|
1511
|
+
pos = 0;
|
1512
|
+
break;
|
1513
|
+
case "last":
|
1514
|
+
pos = tmp.children('ul').children('li').length;
|
1515
|
+
break;
|
1516
|
+
default:
|
1517
|
+
if(!pos) { pos = 0; }
|
1518
|
+
break;
|
1519
|
+
}
|
1520
|
+
if(!this.check("create_node", li, par, pos)) { return false; }
|
1521
|
+
|
1522
|
+
tmp = par === -1 ? this.get_container() : par;
|
1523
|
+
if(!tmp.children("ul").length) { tmp.append("<ul />"); }
|
1524
|
+
if(tmp.children("ul").children("li").eq(pos).length) {
|
1525
|
+
tmp.children("ul").children("li").eq(pos).before(li);
|
1526
|
+
}
|
1527
|
+
else {
|
1528
|
+
tmp.children("ul").append(li);
|
1529
|
+
}
|
1530
|
+
this.correct_node(par, true);
|
1531
|
+
if(callback) { callback.call(this, li); }
|
1532
|
+
this.__callback({ "obj" : li, "parent" : par, "position" : li.index() });
|
1533
|
+
return li;
|
1534
|
+
},
|
1535
|
+
/*
|
1536
|
+
Function: rename_node
|
1537
|
+
This function renames a new node.
|
1538
|
+
|
1539
|
+
Parameters:
|
1540
|
+
obj - *mixed* the node to rename. This is used as a jquery selector, can be jQuery object, DOM node, string, etc.
|
1541
|
+
val - *string* the new title
|
1542
|
+
|
1543
|
+
Triggers:
|
1544
|
+
<rename_node>
|
1545
|
+
|
1546
|
+
Event: rename_node
|
1547
|
+
This event is triggered in the *jstree* namespace when a node is renamed.
|
1548
|
+
|
1549
|
+
Parameters:
|
1550
|
+
data.inst - the instance
|
1551
|
+
data.args - *array* the arguments passed to the function
|
1552
|
+
data.plugin - *string* the function's plugin (here it will be _"core"_ but if the function is extended it may be something else)
|
1553
|
+
data.rslt - *object* which contains a three keys: _obj_ (the node), _title_ (the new title), _old_ (the old title)
|
1554
|
+
|
1555
|
+
Example:
|
1556
|
+
> $("div").bind("rename_node.jstree", function (e, data) {
|
1557
|
+
> alert("Node rename from `" + data.rslt.old + "` to `" + data.rslt.title "`");
|
1558
|
+
> });
|
1559
|
+
*/
|
1560
|
+
rename_node : function (obj, val) {
|
1561
|
+
obj = this.get_node(obj);
|
1562
|
+
var old = this.get_text(obj);
|
1563
|
+
if(!this.check("rename_node", obj, this.get_parent(obj), val)) { return false; }
|
1564
|
+
if(obj && obj.length) {
|
1565
|
+
this.set_text(obj, val); // .apply(this, Array.prototype.slice.call(arguments))
|
1566
|
+
this.__callback({ "obj" : obj, "title" : val, "old" : old });
|
1567
|
+
}
|
1568
|
+
},
|
1569
|
+
/*
|
1570
|
+
Function: delete_node
|
1571
|
+
This function deletes a node.
|
1572
|
+
|
1573
|
+
Parameters:
|
1574
|
+
obj - *mixed* the node to remove. This is used as a jquery selector, can be jQuery object, DOM node, string, etc.
|
1575
|
+
|
1576
|
+
Returns:
|
1577
|
+
mixed - the removed node on success, _false_ on failure
|
1578
|
+
|
1579
|
+
Triggers:
|
1580
|
+
<delete_node>
|
1581
|
+
|
1582
|
+
Event: delete_node
|
1583
|
+
This event is triggered in the *jstree* namespace when a node is deleted.
|
1584
|
+
|
1585
|
+
Parameters:
|
1586
|
+
data.inst - the instance
|
1587
|
+
data.args - *array* the arguments passed to the function
|
1588
|
+
data.plugin - *string* the function's plugin (here it will be _"core"_ but if the function is extended it may be something else)
|
1589
|
+
data.rslt - *object* which contains a three keys: _obj_ (the removed node), _prev_ (the previous sibling of the removed node), _parent_ (the parent of the removed node)
|
1590
|
+
|
1591
|
+
Example:
|
1592
|
+
> $("div").bind("delete_node.jstree", function (e, data) {
|
1593
|
+
> alert("Node deleted!");
|
1594
|
+
> });
|
1595
|
+
*/
|
1596
|
+
delete_node : function (obj) {
|
1597
|
+
obj = this.get_node(obj);
|
1598
|
+
if(!obj || obj === -1 || !obj.length) { return false; }
|
1599
|
+
var par = this.get_parent(obj),
|
1600
|
+
pre = this.get_prev(obj);
|
1601
|
+
if(!this.check("delete_node", obj, par, obj.index())) { return false; }
|
1602
|
+
obj = obj.detach();
|
1603
|
+
this.correct_node(par);
|
1604
|
+
this.correct_node(pre);
|
1605
|
+
this.__callback({ "obj" : obj, "prev" : pre, "parent" : par });
|
1606
|
+
return obj;
|
1607
|
+
},
|
1608
|
+
/*
|
1609
|
+
Function: check
|
1610
|
+
This function checks if a structure modification is valid.
|
1611
|
+
|
1612
|
+
Parameters:
|
1613
|
+
chk - *string* what are we checking (copy_node, move_node, rename_node, create_node, delete_node)
|
1614
|
+
obj - *mixed* the node.
|
1615
|
+
par - *mixed* the parent (if dealing with a move or copy - the new parent).
|
1616
|
+
pos - *mixed* the index among the parent's children (or the new name if dealing with a rename)
|
1617
|
+
is_copy - *boolean* is this a copy or a move call
|
1618
|
+
|
1619
|
+
Returns:
|
1620
|
+
boolean - _true_ if the modification is valid, _false_ otherwise
|
1621
|
+
*/
|
1622
|
+
check : function (chk, obj, par, pos) {
|
1623
|
+
var tmp = chk.match(/^move_node|copy_node|create_node$/i) ? par : obj;
|
1624
|
+
tmp = tmp === -1 ? this.get_container().data('jstree') : tmp.data('jstree');
|
1625
|
+
if(tmp && tmp.functions && tmp.functions[chk]) {
|
1626
|
+
tmp = tmp.functions[chk];
|
1627
|
+
if($.isFunction(tmp)) {
|
1628
|
+
tmp = tmp.call(this, chk, obj, par, pos);
|
1629
|
+
}
|
1630
|
+
if(tmp === false) {
|
1631
|
+
return false;
|
1632
|
+
}
|
1633
|
+
}
|
1634
|
+
switch(chk) {
|
1635
|
+
case "create_node":
|
1636
|
+
break;
|
1637
|
+
case "rename_node":
|
1638
|
+
break;
|
1639
|
+
case "move_node":
|
1640
|
+
tmp = par === -1 ? this.get_container() : par;
|
1641
|
+
tmp = tmp.children('ul').children('li');
|
1642
|
+
if(tmp.length && tmp.index(obj) !== -1 && (pos === obj.index() || pos === obj.index() + 1)) {
|
1643
|
+
return false;
|
1644
|
+
}
|
1645
|
+
if(par !== -1 && par.parentsUntil('.jstree', 'li').andSelf().index(obj) !== -1) {
|
1646
|
+
return false;
|
1647
|
+
}
|
1648
|
+
break;
|
1649
|
+
case "copy_node":
|
1650
|
+
break;
|
1651
|
+
case "delete_node":
|
1652
|
+
break;
|
1653
|
+
}
|
1654
|
+
return true;
|
1655
|
+
},
|
1656
|
+
/*
|
1657
|
+
Function: move_node
|
1658
|
+
This function moves a node.
|
1659
|
+
|
1660
|
+
Parameters:
|
1661
|
+
obj - *mixed* the node to move. This is used as a jquery selector, can be jQuery object, DOM node, string, etc.
|
1662
|
+
parent - *mixed* the new parent. This is used as a jquery selector, can be jQuery object, DOM node, string, etc. Use -1 to promote to a root node.
|
1663
|
+
position - *mixed* where to create the new node. Can be one of "before", "after", "first", "last", "inside" or a numerical index.
|
1664
|
+
callback - optional function to be executed once the node is moved
|
1665
|
+
is_loaded - used internally when a node needs to be loaded - do not pass this
|
1666
|
+
|
1667
|
+
Returns:
|
1668
|
+
boolean - indicating if the move was successfull (may return _undefined_ if the parent node is not yet loaded, but will move the node)
|
1669
|
+
|
1670
|
+
|
1671
|
+
Triggers:
|
1672
|
+
<move_node>
|
1673
|
+
|
1674
|
+
Event: move_node
|
1675
|
+
This event is triggered in the *jstree* namespace when a node is moved.
|
1676
|
+
|
1677
|
+
Parameters:
|
1678
|
+
data.inst - the instance
|
1679
|
+
data.args - *array* the arguments passed to the function
|
1680
|
+
data.plugin - *string* the function's plugin (here it will be _"core"_ but if the function is extended it may be something else)
|
1681
|
+
data.rslt - *object* which contains a five keys: _obj_ (the node), _parent_ (the new parent) and _position_ which is the numerical index, _old_parent_ (the old parent) and is_multi (a boolean indicating if the node is coming from another tree instance)
|
1682
|
+
|
1683
|
+
Example:
|
1684
|
+
> $("div").bind("move_node.jstree", function (e, data) {
|
1685
|
+
> alert("Moved `" + data.inst.get_text(data.rslt.obj) + "` inside `" + (data.rslt.parent === -1 ? 'the main container' : data.inst.get_text(data.rslt.parent)) + "` at index " + data.rslt.position);
|
1686
|
+
> });
|
1687
|
+
*/
|
1688
|
+
move_node : function (obj, par, pos, callback, is_loaded) {
|
1689
|
+
obj = this.get_node(obj);
|
1690
|
+
par = this.get_node(par);
|
1691
|
+
pos = typeof pos === "undefined" ? 0 : pos;
|
1692
|
+
|
1693
|
+
if(!obj || obj === -1 || !obj.length) { return false; }
|
1694
|
+
if(par !== -1 && !par.length) { return false; }
|
1695
|
+
if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {
|
1696
|
+
return this.load_node(par, function () { this.move_node(obj, par, pos, callback, true); });
|
1697
|
+
}
|
1698
|
+
|
1699
|
+
var old_par = this.get_parent(obj),
|
1700
|
+
new_par = (!pos.toString().match(/^(before|after)$/) || par === -1) ? par : this.get_parent(par),
|
1701
|
+
old_ins = $.jstree._reference(obj),
|
1702
|
+
new_ins = par === -1 ? this : $.jstree._reference(par),
|
1703
|
+
is_multi = (old_ins.get_index() !== new_ins.get_index());
|
1704
|
+
if(new_par === -1) {
|
1705
|
+
par = new_ins.get_container();
|
1706
|
+
if(pos === "before") { pos = "first"; }
|
1707
|
+
if(pos === "after") { pos = "last"; }
|
1708
|
+
}
|
1709
|
+
switch(pos) {
|
1710
|
+
case "before":
|
1711
|
+
pos = par.index();
|
1712
|
+
break;
|
1713
|
+
case "after" :
|
1714
|
+
pos = par.index() + 1;
|
1715
|
+
break;
|
1716
|
+
case "inside":
|
1717
|
+
case "first":
|
1718
|
+
pos = 0;
|
1719
|
+
break;
|
1720
|
+
case "last":
|
1721
|
+
pos = par.children('ul').children('li').length;
|
1722
|
+
break;
|
1723
|
+
default:
|
1724
|
+
if(!pos) { pos = 0; }
|
1725
|
+
break;
|
1726
|
+
}
|
1727
|
+
if(!this.check("move_node", obj, new_par, pos)) { return false; }
|
1728
|
+
|
1729
|
+
if(!par.children("ul").length) { par.append("<ul />"); }
|
1730
|
+
if(par.children("ul").children("li").eq(pos).length) {
|
1731
|
+
par.children("ul").children("li").eq(pos).before(obj);
|
1732
|
+
}
|
1733
|
+
else {
|
1734
|
+
par.children("ul").append(obj);
|
1735
|
+
}
|
1736
|
+
|
1737
|
+
if(is_multi) { // if multitree - clean the node recursively - remove all icons, and call deep clean_node
|
1738
|
+
obj.find('.jstree-icon, .jstree-ocl').remove();
|
1739
|
+
this.clean_node(obj);
|
1740
|
+
}
|
1741
|
+
old_ins.correct_node(old_par, true);
|
1742
|
+
new_ins.correct_node(new_par, true);
|
1743
|
+
if(callback) { callback.call(this, obj, new_par, obj.index()); }
|
1744
|
+
this.__callback({ "obj" : obj, "parent" : new_par, "position" : obj.index(), "old_parent" : old_par, "is_multi" : is_multi, 'old_instance' : old_ins, 'new_instance' : new_ins });
|
1745
|
+
return true;
|
1746
|
+
},
|
1747
|
+
/*
|
1748
|
+
Function: copy_node
|
1749
|
+
This function copies a node.
|
1750
|
+
|
1751
|
+
Parameters:
|
1752
|
+
obj - *mixed* the node to copy. This is used as a jquery selector, can be jQuery object, DOM node, string, etc.
|
1753
|
+
parent - *mixed* the new parent. This is used as a jquery selector, can be jQuery object, DOM node, string, etc. Use -1 to promote to a root node.
|
1754
|
+
position - *mixed* where to create the new node. Can be one of "before", "after", "first", "last", "inside" or a numerical index.
|
1755
|
+
callback - optional function to be executed once the node is moved
|
1756
|
+
is_loaded - used internally when a node needs to be loaded - do not pass this
|
1757
|
+
|
1758
|
+
Returns:
|
1759
|
+
boolean - indicating if the move was successfull (may return _undefined_ if the parent node is not yet loaded, but will move the node)
|
1760
|
+
|
1761
|
+
|
1762
|
+
Triggers:
|
1763
|
+
<copy_node>
|
1764
|
+
|
1765
|
+
Event: copy_node
|
1766
|
+
This event is triggered in the *jstree* namespace when a node is copied.
|
1767
|
+
|
1768
|
+
Parameters:
|
1769
|
+
data.inst - the instance
|
1770
|
+
data.args - *array* the arguments passed to the function
|
1771
|
+
data.plugin - *string* the function's plugin (here it will be _"core"_ but if the function is extended it may be something else)
|
1772
|
+
data.rslt - *object* which contains a five keys: _obj_ (the node), _parent_ (the new parent) and _position_ which is the numerical index, _original_ (the original object), is_multi (a boolean indicating if the node is coming from another tree instance, _old_instance_ (the source instance) and _new_instance_ (the receiving instance))
|
1773
|
+
|
1774
|
+
Example:
|
1775
|
+
> $("div").bind("copy_node.jstree", function (e, data) {
|
1776
|
+
> alert("Copied `" + data.inst.get_text(data.rslt.original) + "` inside `" + (data.rslt.parent === -1 ? 'the main container' : data.inst.get_text(data.rslt.parent)) + "` at index " + data.rslt.position);
|
1777
|
+
> });
|
1778
|
+
*/
|
1779
|
+
copy_node : function (obj, par, pos, callback, is_loaded) {
|
1780
|
+
obj = this.get_node(obj);
|
1781
|
+
par = this.get_node(par);
|
1782
|
+
pos = typeof pos === "undefined" ? "last" : pos;
|
1783
|
+
|
1784
|
+
if(!obj || obj === -1 || !obj.length) { return false; }
|
1785
|
+
if(par !== -1 && !par.length) { return false; }
|
1786
|
+
if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) {
|
1787
|
+
return this.load_node(par, function () { this.copy_node(obj, par, pos, callback, true); });
|
1788
|
+
}
|
1789
|
+
var org_obj = obj,
|
1790
|
+
old_par = this.get_parent(obj),
|
1791
|
+
new_par = (!pos.toString().match(/^(before|after)$/) || par === -1) ? par : this.get_parent(par),
|
1792
|
+
old_ins = $.jstree._reference(obj),
|
1793
|
+
new_ins = par === -1 ? this : $.jstree._reference(par),
|
1794
|
+
is_multi = (old_ins.get_index() !== new_ins.get_index());
|
1795
|
+
|
1796
|
+
obj = obj.clone(true);
|
1797
|
+
obj.find("*[id]").andSelf().each(function () {
|
1798
|
+
if(this.id) { this.id = "copy_" + this.id; }
|
1799
|
+
});
|
1800
|
+
if(new_par === -1) {
|
1801
|
+
par = new_ins.get_container();
|
1802
|
+
if(pos === "before") { pos = "first"; }
|
1803
|
+
if(pos === "after") { pos = "last"; }
|
1804
|
+
}
|
1805
|
+
switch(pos) {
|
1806
|
+
case "before":
|
1807
|
+
pos = par.index();
|
1808
|
+
break;
|
1809
|
+
case "after" :
|
1810
|
+
pos = par.index() + 1;
|
1811
|
+
break;
|
1812
|
+
case "inside":
|
1813
|
+
case "first":
|
1814
|
+
pos = 0;
|
1815
|
+
break;
|
1816
|
+
case "last":
|
1817
|
+
pos = par.children('ul').children('li').length;
|
1818
|
+
break;
|
1819
|
+
default:
|
1820
|
+
if(!pos) { pos = 0; }
|
1821
|
+
break;
|
1822
|
+
}
|
1823
|
+
|
1824
|
+
if(!this.check("copy_node", org_obj, new_par, pos)) { return false; }
|
1825
|
+
|
1826
|
+
if(!par.children("ul").length) { par.append("<ul />"); }
|
1827
|
+
if(par.children("ul").children("li").eq(pos).length) {
|
1828
|
+
par.children("ul").children("li").eq(pos).before(obj);
|
1829
|
+
}
|
1830
|
+
else {
|
1831
|
+
par.children("ul").append(obj);
|
1832
|
+
}
|
1833
|
+
if(is_multi) { // if multitree - clean the node recursively - remove all icons, and call deep clean_node
|
1834
|
+
obj.find('.jstree-icon, .jstree-ocl').remove();
|
1835
|
+
}
|
1836
|
+
new_ins.clean_node(obj); // always clean so that selected states, etc. are removed
|
1837
|
+
new_ins.correct_node(new_par, true); // no need to correct the old parent, as nothing has changed there
|
1838
|
+
if(callback) { callback.call(this, obj, new_par, obj.index(), org_obj); }
|
1839
|
+
this.__callback({ "obj" : obj, "parent" : new_par, "old_parent" : old_par, "position" : obj.index(), "original" : org_obj, "is_multi" : is_multi, 'old_instance' : old_ins, 'new_instance' : new_ins });
|
1840
|
+
return true;
|
1841
|
+
},
|
1842
|
+
|
1843
|
+
cut : function (obj) {
|
1844
|
+
obj = this.get_node(obj);
|
1845
|
+
if(!obj || obj === -1 || !obj.length) { return false; }
|
1846
|
+
ccp_node = obj;
|
1847
|
+
ccp_mode = 'move_node';
|
1848
|
+
this.__callback({ "obj" : obj });
|
1849
|
+
},
|
1850
|
+
copy : function (obj) {
|
1851
|
+
obj = this.get_node(obj);
|
1852
|
+
if(!obj || obj === -1 || !obj.length) { return false; }
|
1853
|
+
ccp_node = obj;
|
1854
|
+
ccp_mode = 'copy_node';
|
1855
|
+
this.__callback({ "obj" : obj });
|
1856
|
+
},
|
1857
|
+
can_paste : function () {
|
1858
|
+
return ccp_mode !== false && ccp_node !== false;
|
1859
|
+
},
|
1860
|
+
paste : function (obj) {
|
1861
|
+
obj = this.get_node(obj);
|
1862
|
+
if(!obj || !ccp_mode || !ccp_mode.match(/^(copy_node|move_node)$/) || !ccp_node) { return false; }
|
1863
|
+
this[ccp_mode](ccp_node, obj);
|
1864
|
+
this.__callback({ "obj" : obj, "nodes" : ccp_node, "mode" : ccp_mode });
|
1865
|
+
ccp_node = false;
|
1866
|
+
ccp_mode = false;
|
1867
|
+
},
|
1868
|
+
|
1869
|
+
edit : function (obj, default_text) {
|
1870
|
+
obj = this.get_node(obj);
|
1871
|
+
if(!obj || obj === -1 || !obj.length) { return false; }
|
1872
|
+
obj.parentsUntil(".jstree",".jstree-closed").each($.proxy(function (i, v) {
|
1873
|
+
this.open_node(v, false, 0);
|
1874
|
+
}, this));
|
1875
|
+
var rtl = this.data.core.rtl,
|
1876
|
+
w = this.get_container().width(),
|
1877
|
+
a = obj.children('a:eq(0)'),
|
1878
|
+
oi = obj.children("ins"),
|
1879
|
+
ai = a.children("ins"),
|
1880
|
+
w1 = oi.width() * oi.length,
|
1881
|
+
w2 = ai.width() * ai.length,
|
1882
|
+
t = typeof default_text === 'string' ? default_text : this.get_text(obj),
|
1883
|
+
h1 = $("<div />", { css : { "position" : "absolute", "top" : "-200px", "left" : (rtl ? "0px" : "-1000px"), "visibility" : "hidden" } }).appendTo("body"),
|
1884
|
+
h2 = obj.css("position","relative").append(
|
1885
|
+
$("<input />", {
|
1886
|
+
"value" : t,
|
1887
|
+
"class" : "jstree-rename-input",
|
1888
|
+
// "size" : t.length,
|
1889
|
+
"css" : {
|
1890
|
+
"padding" : "0",
|
1891
|
+
"border" : "1px solid silver",
|
1892
|
+
"position" : "absolute",
|
1893
|
+
"left" : (rtl ? "auto" : (w1 + w2 + 4) + "px"),
|
1894
|
+
"right" : (rtl ? (w1 + w2 + 4) + "px" : "auto"),
|
1895
|
+
"top" : "0px",
|
1896
|
+
"height" : (this.data.core.li_height - 2) + "px",
|
1897
|
+
"lineHeight" : (this.data.core.li_height - 2) + "px",
|
1898
|
+
"width" : "150px" // will be set a bit further down
|
1899
|
+
},
|
1900
|
+
"blur" : $.proxy(function () {
|
1901
|
+
var i = obj.children(".jstree-rename-input"),
|
1902
|
+
v = i.val();
|
1903
|
+
if(v === "") { v = t; }
|
1904
|
+
h1.remove();
|
1905
|
+
i.remove();
|
1906
|
+
this.rename_node(obj, v);
|
1907
|
+
obj.css("position", "");
|
1908
|
+
}, this),
|
1909
|
+
"keyup" : function (event) {
|
1910
|
+
var key = event.keyCode || event.which;
|
1911
|
+
if(key === 27) { this.value = t; this.blur(); return; }
|
1912
|
+
else if(key === 13) { this.blur(); return; }
|
1913
|
+
else { h2.width(Math.min(h1.text("pW" + this.value).width(),w)); }
|
1914
|
+
},
|
1915
|
+
"keypress" : function(event) {
|
1916
|
+
var key = event.keyCode || event.which;
|
1917
|
+
if(key === 13) { return false; }
|
1918
|
+
}
|
1919
|
+
})
|
1920
|
+
).children(".jstree-rename-input"),
|
1921
|
+
fn = {
|
1922
|
+
fontFamily : a.css('fontFamily') || '',
|
1923
|
+
fontSize : a.css('fontSize') || '',
|
1924
|
+
fontWeight : a.css('fontWeight') || '',
|
1925
|
+
fontStyle : a.css('fontStyle') || '',
|
1926
|
+
fontStretch : a.css('fontStretch') || '',
|
1927
|
+
fontVariant : a.css('fontVariant') || '',
|
1928
|
+
letterSpacing : a.css('letterSpacing') || '',
|
1929
|
+
wordSpacing : a.css('wordSpacing') || ''
|
1930
|
+
};
|
1931
|
+
this.set_text(obj, "");
|
1932
|
+
h1.css(fn);
|
1933
|
+
h2.css(fn).width(Math.min(h1.text("pW" + h2[0].value).width(),w))[0].select();
|
1934
|
+
}
|
1935
|
+
}
|
1936
|
+
});
|
1937
|
+
|
1938
|
+
// add core CSS
|
1939
|
+
$(function() {
|
1940
|
+
var css_string = '' +
|
1941
|
+
'.jstree ul, .jstree li { display:block; margin:0 0 0 0; padding:0 0 0 0; list-style-type:none; } ' +
|
1942
|
+
'.jstree li { display:block; min-height:18px; line-height:18px; white-space:nowrap; margin-left:18px; min-width:18px; } ' +
|
1943
|
+
'.jstree-rtl li { margin-left:0; margin-right:18px; } ' +
|
1944
|
+
'.jstree > ul > li { margin-left:0px; } ' +
|
1945
|
+
'.jstree-rtl > ul > li { margin-right:0px; } ' +
|
1946
|
+
'.jstree .jstree-icon { display:inline-block; text-decoration:none; margin:0; padding:0; vertical-align:top; } ' +
|
1947
|
+
'.jstree .jstree-ocl { width:18px; height:18px; text-align:center; line-height:18px; cursor:default; vertical-align:top; } ' +
|
1948
|
+
'.jstree a { display:inline-block; line-height:16px; height:16px; color:black; white-space:nowrap; padding:1px 2px; margin:0; } ' +
|
1949
|
+
'.jstree a:focus { outline: none; } ' +
|
1950
|
+
'li.jstree-open > ul { display:block; } ' +
|
1951
|
+
'li.jstree-closed > ul { display:none; } ';
|
1952
|
+
// Correct IE 6 (does not support the > CSS selector)
|
1953
|
+
if($.jstree.IS_IE6) {
|
1954
|
+
try { document.execCommand("BackgroundImageCache", false, true); } catch (err) { } // prevents flickers
|
1955
|
+
css_string += '' +
|
1956
|
+
'.jstree li { height:18px; margin-left:0; margin-right:0; } ' +
|
1957
|
+
'.jstree li li { margin-left:18px; } ' +
|
1958
|
+
'.jstree-rtl li li { margin-left:0px; margin-right:18px; } ' +
|
1959
|
+
'li.jstree-open ul { display:block; } ' +
|
1960
|
+
'li.jstree-closed ul { display:none !important; } ' +
|
1961
|
+
'.jstree li a { display:inline; border-width:0 !important; padding:0px 2px !important; } ';
|
1962
|
+
}
|
1963
|
+
// Correct IE 7 (shifts anchor nodes onhover)
|
1964
|
+
if($.jstree.IS_IE7) {
|
1965
|
+
css_string += '.jstree li a { border-width:0 !important; padding:0px 2px !important; } ';
|
1966
|
+
}
|
1967
|
+
// Correct ff2 lack of display:inline-block
|
1968
|
+
if($.jstree.IS_FF2) {
|
1969
|
+
css_string += '' +
|
1970
|
+
'.jstree .jstree-icon { display:-moz-inline-box; } ' +
|
1971
|
+
'.jstree li { line-height:12px; } ' + // WHY??
|
1972
|
+
'.jstree a { display:-moz-inline-box; } ';
|
1973
|
+
/* за темите
|
1974
|
+
'.jstree .jstree-no-icons .jstree-checkbox { display:-moz-inline-stack !important; } ';
|
1975
|
+
*/
|
1976
|
+
}
|
1977
|
+
// the default stylesheet
|
1978
|
+
$.vakata.css.add_sheet({ str : css_string, title : "jstree" });
|
1979
|
+
});
|
1980
|
+
})(jQuery);
|
1981
|
+
|
1982
|
+
})();
|