misc.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  1. /* global jQuery */
  2. // disable all events
  3. (function ($, undefined) {
  4. "use strict";
  5. $.jstree.plugins.trigger = function (options, parent) {
  6. this.init = function (el, options) {
  7. // do not forget parent
  8. parent.init.call(this, el, options);
  9. this._data.trigger.disabled = false;
  10. };
  11. this.trigger = function (ev, data) {
  12. if(!this._data.trigger.disabled) {
  13. parent.trigger.call(this, ev, data);
  14. }
  15. };
  16. this.disable_events = function () { this._data.trigger.disabled = true; };
  17. this.enable_events = function () { this._data.trigger.disabled = false; };
  18. };
  19. })(jQuery);
  20. // mapping
  21. (function ($, undefined) {
  22. "use strict";
  23. // use this if you need any options
  24. $.jstree.defaults.mapper = {
  25. option_key : "option_value"
  26. };
  27. $.jstree.plugins.mapper = function () {
  28. this._parse_model_from_json = function (d, p, ps) {
  29. // d is the node from the server, it will be called recursively for children,
  30. // so you do not need to process at once
  31. /* // for example
  32. for(var i in d) {
  33. if(d.hasOwnProperty(i)) {
  34. d[i.toLowerCase()] = d[i];
  35. }
  36. }
  37. */
  38. return parent._parse_model_from_json.call(this, d, p, ps);
  39. };
  40. };
  41. })(jQuery);
  42. // no hover
  43. (function ($, undefined) {
  44. "use strict";
  45. $.jstree.plugins.nohover = function () {
  46. this.hover_node = $.noop;
  47. };
  48. })(jQuery);
  49. // force multiple select
  50. (function ($, undefined) {
  51. "use strict";
  52. $.jstree.defaults.multiselect = {};
  53. $.jstree.plugins.multiselect = function (options, parent) {
  54. this.activate_node = function (obj, e) {
  55. e.ctrlKey = true;
  56. parent.activate_node.call(this, obj, e);
  57. };
  58. };
  59. })(jQuery);
  60. // real checkboxes
  61. (function ($, undefined) {
  62. "use strict";
  63. var inp = document.createElement("INPUT");
  64. inp.type = "checkbox";
  65. inp.className = "jstree-checkbox jstree-realcheckbox";
  66. $.jstree.defaults.realcheckboxes = {};
  67. $.jstree.plugins.realcheckboxes = function (options, parent) {
  68. this.bind = function () {
  69. parent.bind.call(this);
  70. this._data.realcheckboxes.uto = false;
  71. this.element
  72. .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 ready.jstree loaded.jstree', function () {
  73. // only if undetermined is in setting
  74. if(this._data.realcheckboxes.uto) { clearTimeout(this._data.realcheckboxes.uto); }
  75. this._data.realcheckboxes.uto = setTimeout(this._realcheckboxes.bind(this), 50);
  76. }.bind(this));
  77. };
  78. this.redraw_node = function(obj, deep, callback, force_draw) {
  79. obj = parent.redraw_node.call(this, obj, deep, callback, force_draw);
  80. if(obj) {
  81. var i, j, tmp = null, chk = inp.cloneNode(true);
  82. for(i = 0, j = obj.childNodes.length; i < j; i++) {
  83. if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) {
  84. tmp = obj.childNodes[i];
  85. break;
  86. }
  87. }
  88. if(tmp) {
  89. for(i = 0, j = tmp.childNodes.length; i < j; i++) {
  90. if(tmp.childNodes[i] && tmp.childNodes[i].className && tmp.childNodes[i].className.indexOf("jstree-checkbox") !== -1) {
  91. tmp = tmp.childNodes[i];
  92. break;
  93. }
  94. }
  95. }
  96. if(tmp && tmp.tagName === "I") {
  97. tmp.style.backgroundColor = "transparent";
  98. tmp.style.backgroundImage = "none";
  99. tmp.appendChild(chk);
  100. }
  101. }
  102. return obj;
  103. };
  104. this._realcheckboxes = function () {
  105. var ts = this.settings.checkbox.tie_selection;
  106. console.log(ts);
  107. $('.jstree-realcheckbox').each(function () {
  108. this.checked = (!ts && this.parentNode.parentNode.className.indexOf("jstree-checked") !== -1) || (ts && this.parentNode.parentNode.className.indexOf('jstree-clicked') !== -1);
  109. this.indeterminate = this.parentNode.className.indexOf("jstree-undetermined") !== -1;
  110. this.disabled = this.parentNode.parentNode.className.indexOf("disabled") !== -1;
  111. });
  112. };
  113. };
  114. })(jQuery);
  115. // no state
  116. (function ($, undefined) {
  117. "use strict";
  118. $.jstree.plugins.nostate = function () {
  119. this.set_state = function (state, callback) {
  120. if(callback) { callback.call(this); }
  121. this.trigger('set_state');
  122. };
  123. };
  124. })(jQuery);
  125. // no selected in state
  126. (function ($, undefined) {
  127. "use strict";
  128. $.jstree.plugins.noselectedstate = function (options, parent) {
  129. this.get_state = function () {
  130. var state = parent.get_state.call(this);
  131. delete state.core.selected;
  132. return state;
  133. };
  134. };
  135. })(jQuery);
  136. // additional icon on node (outside of anchor)
  137. (function ($, undefined) {
  138. "use strict";
  139. var img = document.createElement('IMG');
  140. //img.src = "http://www.dpcd.vic.gov.au/__data/assets/image/0004/30667/help.gif";
  141. img.className = "jstree-questionmark";
  142. $.jstree.defaults.questionmark = $.noop;
  143. $.jstree.plugins.questionmark = function (options, parent) {
  144. this.bind = function () {
  145. parent.bind.call(this);
  146. this.element
  147. .on("click.jstree", ".jstree-questionmark", function (e) {
  148. e.stopImmediatePropagation();
  149. this.settings.questionmark.call(this, this.get_node(e.target));
  150. }.bind(this));
  151. };
  152. this.teardown = function () {
  153. if(this.settings.questionmark) {
  154. this.element.find(".jstree-questionmark").remove();
  155. }
  156. parent.teardown.call(this);
  157. };
  158. this.redraw_node = function(obj, deep, callback, force_draw) {
  159. obj = parent.redraw_node.call(this, obj, deep, callback, force_draw);
  160. if(obj) {
  161. var tmp = img.cloneNode(true);
  162. obj.insertBefore(tmp, obj.childNodes[2]);
  163. }
  164. return obj;
  165. };
  166. };
  167. })(jQuery);
  168. // auto numbering
  169. (function ($, undefined) {
  170. "use strict";
  171. var span = document.createElement('SPAN');
  172. span.className = "jstree-numbering";
  173. $.jstree.defaults.numbering = {};
  174. $.jstree.plugins.numbering = function (options, parent) {
  175. this.teardown = function () {
  176. if(this.settings.questionmark) {
  177. this.element.find(".jstree-numbering").remove();
  178. }
  179. parent.teardown.call(this);
  180. };
  181. this.get_number = function (obj) {
  182. obj = this.get_node(obj);
  183. var ind = $.inArray(obj.id, this.get_node(obj.parent).children) + 1;
  184. return obj.parent === '#' ? ind : this.get_number(obj.parent) + '.' + ind;
  185. };
  186. this.redraw_node = function(obj, deep, callback, force_draw) {
  187. var i, j, tmp = null, elm = null, org = this.get_number(obj);
  188. obj = parent.redraw_node.call(this, obj, deep, callback, force_draw);
  189. if(obj) {
  190. for(i = 0, j = obj.childNodes.length; i < j; i++) {
  191. if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) {
  192. tmp = obj.childNodes[i];
  193. break;
  194. }
  195. }
  196. if(tmp) {
  197. elm = span.cloneNode(true);
  198. elm.innerHTML = org + '. ';
  199. tmp.insertBefore(elm, tmp.childNodes[tmp.childNodes.length - 1]);
  200. }
  201. }
  202. return obj;
  203. };
  204. };
  205. })(jQuery);
  206. // additional icon on node (inside anchor)
  207. (function ($, undefined) {
  208. "use strict";
  209. var _s = document.createElement('SPAN');
  210. _s.className = 'fa-stack jstree-stackedicon';
  211. var _i = document.createElement('I');
  212. _i.className = 'jstree-icon';
  213. _i.setAttribute('role', 'presentation');
  214. $.jstree.plugins.stackedicon = function (options, parent) {
  215. this.teardown = function () {
  216. this.element.find(".jstree-stackedicon").remove();
  217. parent.teardown.call(this);
  218. };
  219. this.redraw_node = function(obj, deep, is_callback, force_render) {
  220. obj = parent.redraw_node.apply(this, arguments);
  221. if(obj) {
  222. var i, j, tmp = null, icon = null, temp = null;
  223. for(i = 0, j = obj.childNodes.length; i < j; i++) {
  224. if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) {
  225. tmp = obj.childNodes[i];
  226. break;
  227. }
  228. }
  229. if(tmp) {
  230. if(this._model.data[obj.id].state.icons && this._model.data[obj.id].state.icons.length) {
  231. icon = _s.cloneNode(false);
  232. for(i = 0, j = this._model.data[obj.id].state.icons.length; i < j; i++) {
  233. temp = _i.cloneNode(false);
  234. temp.className += ' ' + this._model.data[obj.id].state.icons[i];
  235. icon.appendChild(temp);
  236. }
  237. tmp.insertBefore(icon, tmp.childNodes[0]);
  238. }
  239. }
  240. }
  241. return obj;
  242. };
  243. };
  244. })(jQuery);
  245. // selecting a node opens it
  246. (function ($, undefined) {
  247. "use strict";
  248. $.jstree.plugins.selectopens = function (options, parent) {
  249. this.bind = function () {
  250. parent.bind.call(this);
  251. this.element.on('select_node.jstree', function (e, data) { data.instance.open_node(data.node); });
  252. };
  253. };
  254. })(jQuery);
  255. // object as data
  256. (function ($, undefined) {
  257. "use strict";
  258. $.jstree.defaults.datamodel = {};
  259. $.jstree.plugins.datamodel = function (options, parent) {
  260. this.init = function (el, options) {
  261. this._data.datamodel = {};
  262. parent.init.call(this, el, options);
  263. };
  264. this._datamodel = function (id, nodes, callback) {
  265. var i = 0, j = nodes.length, tmp = [], obj = null;
  266. for(; i < j; i++) {
  267. this._data.datamodel[nodes[i].getID()] = nodes[i];
  268. obj = {
  269. id : nodes[i].getID(),
  270. text : nodes[i].getText(),
  271. children : nodes[i].hasChildren()
  272. };
  273. if(nodes[i].getExtra) {
  274. obj = nodes[i].getExtra(obj); // icon, type
  275. }
  276. tmp.push(obj);
  277. }
  278. return this._append_json_data(id, tmp, function (status) {
  279. callback.call(this, status);
  280. }.bind(this));
  281. };
  282. this._load_node = function (obj, callback) {
  283. var id = obj.id;
  284. var nd = obj.id === "#" ? this.settings.core.data : this._data.datamodel[obj.id].getChildren(function (nodes) {
  285. this._datamodel(id, nodes, callback);
  286. }.bind(this));
  287. if($.vakata.is_array(nd)) {
  288. this._datamodel(id, nd, callback);
  289. }
  290. };
  291. };
  292. })(jQuery);
  293. /*
  294. demo of the above
  295. function treeNode(val) {
  296. var id = ++treeNode.counter;
  297. this.getID = function () {
  298. return id;
  299. };
  300. this.getText = function () {
  301. return val.toString();
  302. };
  303. this.getExtra = function (obj) {
  304. obj.icon = false;
  305. return obj;
  306. };
  307. this.hasChildren = function () {
  308. return true;
  309. };
  310. this.getChildren = function () {
  311. return [
  312. new treeNode(Math.pow(val, 2)),
  313. new treeNode(Math.sqrt(val)),
  314. ];
  315. };
  316. }
  317. treeNode.counter = 0;
  318. $('#jstree').jstree({
  319. 'core': {
  320. 'data': [
  321. new treeNode(2),
  322. new treeNode(3),
  323. new treeNode(4),
  324. new treeNode(5)
  325. ]
  326. },
  327. plugins : ['datamodel']
  328. });
  329. */
  330. // untested sample plugin to keep all nodes in the DOM
  331. (function ($, undefined) {
  332. "use strict";
  333. $.jstree.plugins.dom = function (options, parent) {
  334. this.redraw_node = function (node, deep, is_callback, force_render) {
  335. return parent.redraw_node.call(this, node, deep, is_callback, true);
  336. };
  337. this.close_node = function (obj, animation) {
  338. var t1, t2, t, d;
  339. if($.vakata.is_array(obj)) {
  340. obj = obj.slice();
  341. for(t1 = 0, t2 = obj.length; t1 < t2; t1++) {
  342. this.close_node(obj[t1], animation);
  343. }
  344. return true;
  345. }
  346. obj = this.get_node(obj);
  347. if(!obj || obj.id === $.jstree.root) {
  348. return false;
  349. }
  350. if(this.is_closed(obj)) {
  351. return false;
  352. }
  353. animation = animation === undefined ? this.settings.core.animation : animation;
  354. t = this;
  355. d = this.get_node(obj, true);
  356. if(d.length) {
  357. if(!animation) {
  358. d[0].className = d[0].className.replace('jstree-open', 'jstree-closed');
  359. d.attr("aria-expanded", false);
  360. }
  361. else {
  362. d
  363. .children(".jstree-children").attr("style","display:block !important").end()
  364. .removeClass("jstree-open").addClass("jstree-closed").attr("aria-expanded", false)
  365. .children(".jstree-children").stop(true, true).slideUp(animation, function () {
  366. this.style.display = "";
  367. t.trigger("after_close", { "node" : obj });
  368. });
  369. }
  370. }
  371. obj.state.opened = false;
  372. this.trigger('close_node',{ "node" : obj });
  373. if(!animation || !d.length) {
  374. this.trigger("after_close", { "node" : obj });
  375. }
  376. };
  377. };
  378. })(jQuery);
  379. // customize plugin by @Lusito
  380. // https://github.com/Lusito/jstree/blob/node-customize/src/jstree-node-customize.js
  381. /**
  382. * ### Node Customize plugin
  383. *
  384. * Allows to customize nodes when they are drawn.
  385. */
  386. (function (factory) {
  387. "use strict";
  388. if (typeof define === 'function' && define.amd) {
  389. define('jstree.node_customize', ['jquery','./jstree.js'], factory);
  390. }
  391. else if(typeof exports === 'object') {
  392. factory(require('jquery'), require('./jstree.js'));
  393. }
  394. else {
  395. factory(jQuery, jQuery.jstree);
  396. }
  397. }(function ($, jstree, undefined) {
  398. "use strict";
  399. if($.jstree.plugins.node_customize) { return; }
  400. /**
  401. * the settings object.
  402. * key is the attribute name to select the customizer function from switch.
  403. * switch is a key => function(el, node) map.
  404. * default: function(el, node) will be called if the type could not be mapped
  405. * @name $.jstree.defaults.node_customize
  406. * @plugin node_customize
  407. */
  408. $.jstree.defaults.node_customize = {
  409. "key": "type",
  410. "switch": {},
  411. "default": null
  412. };
  413. $.jstree.plugins.node_customize = function (options, parent) {
  414. this.redraw_node = function (obj, deep, callback, force_draw) {
  415. var el = parent.redraw_node.apply(this, arguments);
  416. if (el) {
  417. var node = this.get_node(obj);
  418. var cfg = this.settings.node_customize;
  419. var key = cfg.key;
  420. var type = (node && node.original && node.original[key]);
  421. var customizer = (type && cfg.switch[type]) || cfg.default;
  422. if(customizer)
  423. customizer(el, node);
  424. }
  425. return el;
  426. };
  427. }
  428. }));
  429. // parentsload plugin by @ashl1
  430. /**
  431. * ### Parentsload plugin
  432. *
  433. * Change load_node() functionality in jsTree, to possible load not yes downloaded node with all it parent in a single request (only useful with lazy loading).
  434. *
  435. * version 1.0.0 (Alexey Shildyakov - ashl1future@gmail.com)
  436. * 2015: Compatible with jsTree-3.2.1
  437. */
  438. /*globals jQuery, define, exports, require, document */
  439. (function (factory) {
  440. "use strict";
  441. if (typeof define === 'function' && define.amd) {
  442. define('jstree.parentsload', ['jquery','./jstree.js'], factory);
  443. }
  444. else if(typeof exports === 'object') {
  445. factory(require('jquery'), require('./jstree.js'));
  446. }
  447. else {
  448. factory(jQuery, jQuery.jstree);
  449. }
  450. }(function ($, jstree, undefined) {
  451. "use strict";
  452. if($.jstree.plugins.parentsload) { return; }
  453. /**
  454. * parentsload configuration
  455. *
  456. * The configuration syntax is almost the same as for core.data option. You must set parenstload.data the following:
  457. *
  458. * parentsload: {
  459. * data: function(){} // this function overwrites core data.data options
  460. * }
  461. *
  462. * OR
  463. *
  464. * parentsload: {
  465. * data: {
  466. * url: function(node){} OR string,
  467. * data: function(node){} OR associative array as json{data} jQuery parameter
  468. * }
  469. * }
  470. *
  471. * In last case at least on of 'url' or 'data' must be presented.
  472. *
  473. * At first, the plugin load_node() detects if the node already downloaded. If is - uses the core.data settings, if not - uses parentsload.data settings
  474. * to fetch in one query the specified node and all its parent. The data must be in the first mentioned JSON format with set nested children[].
  475. * Each node level should consist of all nodes on the level to properly work with the tree in the future. Otherwise, you must manually call load_node
  476. * on every parent node to fetch all children nodes on that level.
  477. *
  478. * @name $.jstree.defaults.parentsload
  479. * @plugin parentsload
  480. */
  481. $.jstree.defaults.parentsload = null;
  482. $.jstree.plugins.parentsload = function (options, parent) {
  483. this.init = function (el, options) {
  484. parent.init.call(this, el, options);
  485. this.patch_data()
  486. };
  487. this.patch_data = function(){
  488. var parentsloadSettings = this.settings.parentsload;
  489. var jsTreeDataSettings = this.settings.core.data;
  490. var self = this;
  491. var callError = function(number, message) {
  492. self._data.core.last_error = { 'error' : 'configuration', 'plugin' : 'parentsload', 'id' : 'parentsload_' + number, 'reason' : message, 'data' : JSON.stringify({config: parentsloadSettings}) };
  493. self.settings.core.error.call(self, self._data.core.last_error);
  494. }
  495. if(!parentsloadSettings) {
  496. callError('01', 'The configuration must be presented')
  497. return
  498. }
  499. parentsloadSettings = parentsloadSettings.data;
  500. var patchSettingsProperty = function (propertyName) {
  501. var property = parentsloadSettings[propertyName],
  502. coreProperty = jsTreeDataSettings[propertyName];
  503. if (property) {
  504. jsTreeDataSettings[propertyName] = function(node) {
  505. if (this.get_node(node).parentsload_required) {
  506. if ($.vakata.is_function(property)) {
  507. return property.call(this, node)
  508. } else {// (typeof property === 'string')
  509. return property
  510. }
  511. } else {
  512. if ($.vakata.is_function(coreProperty)) {
  513. return coreProperty.call(this, node)
  514. } else { // (typeof coreProperty === 'string')
  515. return coreProperty
  516. }
  517. }
  518. }
  519. } /* else {
  520. use jstree the same data[propertyName] settings
  521. }*/
  522. }
  523. if($.vakata.is_function(parentsloadSettings)) {
  524. this.settings.data = parentsloadSettings
  525. } else if (typeof parentsloadSettings === 'object') {
  526. if (! (parentsloadSettings.url || parentsloadSettings.data)) {
  527. callError('02', 'The "data.url" or "data.data" must be presented in configuration')
  528. return
  529. }
  530. patchSettingsProperty('url')
  531. patchSettingsProperty('data')
  532. } else {
  533. callError('03', 'The appropriate "data.url" or "data.data" must be presented in configuration')
  534. }
  535. }
  536. this.load_node = function (obj, callback) {
  537. if($.vakata.is_array(obj)) {
  538. // FIXME: _load_nodes will not load nodes not presented in the tree
  539. this._load_nodes(obj.slice(), callback);
  540. return true;
  541. }
  542. var foundObj = this.get_node(obj);
  543. if (foundObj) {
  544. return parent.load_node.apply(this, arguments)
  545. } else {
  546. // node hasn't been loaded
  547. var id = (obj.id || obj.id === 0) ? obj.id : obj;
  548. this._model.data[id] = {
  549. id : id,
  550. parent : '#',
  551. parents : [],
  552. children : [],
  553. children_d : [],
  554. state : { loaded : false },
  555. li_attr : {},
  556. a_attr : {},
  557. parentsload_required : true,
  558. };
  559. return parent.load_node.call(this, obj, function(obj, status){
  560. obj.parentsload_required = !status
  561. callback.call(this, obj, status)
  562. })
  563. }
  564. }
  565. };
  566. }));
  567. // conditional deselect
  568. (function (factory) {
  569. "use strict";
  570. if (typeof define === 'function' && define.amd) {
  571. define('jstree.conditionaldeselect', ['jquery','./jstree.js'], factory);
  572. }
  573. else if(typeof exports === 'object') {
  574. factory(require('jquery'), require('./jstree.js'));
  575. }
  576. else {
  577. factory(jQuery, jQuery.jstree);
  578. }
  579. }(function ($, jstree, undefined) {
  580. "use strict";
  581. if($.jstree.plugins.conditionaldeselect) { return; }
  582. $.jstree.defaults.conditionaldeselect = function () { return true; };
  583. $.jstree.plugins.conditionaldeselect = function (options, parent) {
  584. // own function
  585. this.deselect_node = function (obj, supress_event, e) {
  586. if(this.settings.conditionaldeselect.call(this, this.get_node(obj), e)) {
  587. return parent.deselect_node.call(this, obj, supress_event, e);
  588. }
  589. };
  590. };
  591. }));
  592. // conditional close
  593. (function (factory) {
  594. "use strict";
  595. if (typeof define === 'function' && define.amd) {
  596. define('jstree.conditionalclose', ['jquery','./jstree.js'], factory);
  597. }
  598. else if(typeof exports === 'object') {
  599. factory(require('jquery'), require('./jstree.js'));
  600. }
  601. else {
  602. factory(jQuery, jQuery.jstree);
  603. }
  604. }(function ($, jstree, undefined) {
  605. "use strict";
  606. if($.jstree.plugins.conditionalclose) { return; }
  607. $.jstree.defaults.conditionalclose = function () { return true; };
  608. $.jstree.plugins.conditionalclose = function (options, parent) {
  609. // own function
  610. this.close_node = function (obj, animation) {
  611. if(this.settings.conditionalclose.close.call(this, this.get_node(obj), e)) {
  612. return parent.deselect_node.call(this, obj, animation);
  613. }
  614. };
  615. };
  616. }));
  617. // separate items and badges plugin by vdkkia (vahidkiani88@gmail.com)
  618. // https://github.com/vdkkia/jstree
  619. //
  620. //CSS:
  621. //.separator{border-bottom:1px solid;border-image-source:linear-gradient(45deg,rgba(0,0,0,0),rgba(0,0,0,.1),rgba(0,0,0,0));border-image-slice:1;width:100%;left:0;color:#aaa;font-size:10px;font-weight:400;float:right;text-align:right;padding-right:20px;position:absolute;z-index:-1}.treeaction{color:#555;margin-left:3px;padding:2px;font-weight:700;font-size:10px;border:none;background-color:#fff;transition:all .2s ease-in-out;text-decoration:none;float:right;margin-right:2px;top:4px}.treeaction:hover{color:green;text-decoration:none;transform:scale(1.5)}
  622. (function (factory) {
  623. }(function ($, jstree, undefined) {
  624. "use strict";
  625. $.jstree.plugins.node_customize = function (options, parent) {
  626. this.redraw_node = function (obj, deep, callback, force_draw) {
  627. var el = parent.redraw_node.apply(this, arguments);
  628. if (el) {
  629. var node = this.get_node(obj);
  630. var cfg = this.settings.node_customize;
  631. var key = cfg.key;
  632. var type = (node && node.original && node.original[key]);
  633. var customizer = (type && cfg.switch[type]) || cfg.default;
  634. if(customizer)
  635. customizer(el, node);
  636. }
  637. return el;
  638. };
  639. }
  640. }));
  641. // Use material icons
  642. // Plugin by KSD-France (https://github.com/KSD-France/, dev@ksd.fr)
  643. (function ($, undefined) {
  644. "use strict";
  645. $.jstree.plugins.material = function (options, parent) {
  646. this.teardown = function () {
  647. this.element.find(".material-icons").remove();
  648. parent.teardown.call(this);
  649. };
  650. this.redraw_node = function (obj, deep, is_callback, force_render) {
  651. obj = parent.redraw_node.apply(this, arguments);
  652. if (obj) {
  653. var i,
  654. j,
  655. tmp = null,
  656. icon = null,
  657. temp = null;
  658. for(i = 0, j = obj.childNodes.length; i < j; i++) {
  659. if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) {
  660. tmp = obj.childNodes[i];
  661. break;
  662. }
  663. }
  664. if (tmp) {
  665. if (this._model.data[obj.id].icon && this._model.data[obj.id].icon.length) {
  666. tmp.childNodes[0].className += " material-icons";
  667. tmp.childNodes[0].innerHTML = this._model.data[obj.id].icon;
  668. }
  669. }
  670. }
  671. return obj;
  672. }
  673. }
  674. })(jQuery);
  675. // overwrite select_all
  676. (function ($, undefined) {
  677. "use strict";
  678. if($.jstree.plugins.select_all) { return; }
  679. $.jstree.defaults.select_all = {
  680. hidden : true,
  681. disabled : true
  682. };
  683. $.jstree.plugins.select_all = function (options, parent) {
  684. this._select_all = function (id) {
  685. var obj = this.get_node(id), i, j, c, s = this.settings.select_all;
  686. if (!obj || !obj.children || !obj.children.length) {
  687. return;
  688. }
  689. for (i = 0, j = obj.children.length; i < j; i++) {
  690. c = this.get_node(obj.children[i]);
  691. if (c && !c.state.selected && (s.disabled || !c.state.disabled) && (s.hidden || !c.state.hidden)) {
  692. this._data.core.selected.push(c.id);
  693. if (c.children && c.children.length) {
  694. this._select_all(c.id);
  695. }
  696. }
  697. }
  698. };
  699. this.select_all = function (supress_event) {
  700. var tmp = this._data.core.selected.concat([]), i, j;
  701. this._select_all('#');
  702. this.redraw(true);
  703. /**
  704. * triggered when all nodes are selected
  705. * @event
  706. * @name select_all.jstree
  707. * @param {Array} selected the current selection
  708. */
  709. this.trigger('select_all', { 'selected' : this._data.core.selected });
  710. if(!supress_event) {
  711. this.trigger('changed', { 'action' : 'select_all', 'selected' : this._data.core.selected, 'old_selection' : tmp });
  712. }
  713. };
  714. }
  715. })(jQuery);