grid.treegrid.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682
  1. /**
  2. * jqGrid extension - Tree Grid
  3. * Copyright (c) 2008-2014, Tony Tomov, tony@trirand.com
  4. * Copyright (c) 2014-2018, Oleg Kiriljuk, oleg.kiriljuk@ok-soft-gmbh.com
  5. * Dual licensed under the MIT and GPL licenses:
  6. * http://www.opensource.org/licenses/mit-license.php
  7. * http://www.gnu.org/licenses/gpl-2.0.html
  8. **/
  9. /*jshint eqeqeq:false */
  10. /*jslint browser: true, eqeq: true, plusplus: true, nomen: true, unparam: true, vars: true, white: true, todo: true */
  11. /*global jQuery, define, exports, module, require */
  12. (function (factory) {
  13. "use strict";
  14. if (typeof define === "function" && define.amd) {
  15. // AMD. Register as an anonymous module.
  16. define([
  17. "jquery",
  18. "./grid.base"
  19. ], factory);
  20. } else if (typeof module === "object" && module.exports) {
  21. // Node/CommonJS
  22. module.exports = function (root, $) {
  23. if (!root) {
  24. root = window;
  25. }
  26. if ($ === undefined) {
  27. // require("jquery") returns a factory that requires window to
  28. // build a jQuery instance, we normalize how we use modules
  29. // that require this pattern but the window provided is a noop
  30. // if it's defined (how jquery works)
  31. $ = typeof window !== "undefined" ?
  32. require("jquery") :
  33. require("jquery")(root);
  34. }
  35. require("./grid.base");
  36. factory($);
  37. return $;
  38. };
  39. } else {
  40. // Browser globals
  41. factory(jQuery);
  42. }
  43. }(function ($) {
  44. "use strict";
  45. var jgrid = $.jgrid, getAccessor = jgrid.getAccessor, stripPref = jgrid.stripPref,
  46. jqID = jgrid.jqID, base = $.fn.jqGrid;
  47. // begin module grid.treegrid
  48. var treeGridFeedback = function () {
  49. var args = $.makeArray(arguments);
  50. args[0] = "treeGrid" + args[0].charAt(0).toUpperCase() + args[0].substring(1);
  51. args.unshift("");
  52. args.unshift("");
  53. args.unshift(this.p);
  54. return jgrid.feedback.apply(this, args);
  55. },
  56. getNodeIcons = function (p, item) {
  57. var icons = item[p.treeReader.icon_field],
  58. treeIcons = p.treeIcons,
  59. iconCollapsed = treeIcons.plus + " tree-plus",
  60. iconExpanded = treeIcons.minus + " tree-minus";
  61. if (icons && typeof icons === "string") {
  62. icons = icons.split(",");
  63. if (icons.length === 2) {
  64. iconExpanded = icons[0];
  65. iconCollapsed = icons[1];
  66. }
  67. }
  68. return {
  69. expanded: iconExpanded,
  70. collapsed: iconCollapsed,
  71. common: treeIcons.commonIconClass
  72. };
  73. };
  74. jgrid.extend({
  75. setTreeNode: function () {
  76. // TODO: Move the code in setTreeGrid because it uses currently no parameters
  77. // and it's don't make any actions with specific row
  78. return this.each(function () {
  79. var $t = this, $self = $($t), p = $t.p;
  80. if (!$t.grid || !p.treeGrid) { return; }
  81. var expanded = p.treeReader.expanded_field,
  82. isLeaf = p.treeReader.leaf_field,
  83. beforeSelectRow = function (e, rowid, eOrg) {
  84. if (eOrg != null) {
  85. var $target = $(eOrg.target),
  86. $td = $target.closest("tr.jqgrow>td"),
  87. $tr = $td.parent(),
  88. expendOrCollaps = function () {
  89. var item = p.data[p._index[stripPref(p.idPrefix, rowid)]],
  90. collapseOrExpand = item[expanded] ? "collapse" : "expand";
  91. if (!item[isLeaf]) {
  92. base[collapseOrExpand + "Row"].call($self, item, $tr);
  93. base[collapseOrExpand + "Node"].call($self, item, $tr);
  94. }
  95. };
  96. if ($target.is("div.treeclick")) {
  97. expendOrCollaps();
  98. } else if (p.ExpandColClick) {
  99. if ($td.length > 0 && $target.closest("span.cell-wrapper", $td).length > 0) {
  100. expendOrCollaps();
  101. }
  102. }
  103. return true; // allow selection
  104. }
  105. };
  106. $self.off("jqGridBeforeSelectRow.setTreeNode");
  107. $self.on("jqGridBeforeSelectRow.setTreeNode", beforeSelectRow);
  108. });
  109. },
  110. setTreeGrid: function () {
  111. return this.each(function () {
  112. var $t = this, p = $t.p, nm, key, tkey, dupcols = [],
  113. boolProp = ["leaf_field", "expanded_field", "loaded"];
  114. if (!p.treeGrid) { return; }
  115. if (!p.treedatatype) { $.extend($t.p, { treedatatype: p.datatype }); }
  116. p.subGrid = false;
  117. p.altRows = false;
  118. p.pgbuttons = false;
  119. p.pginput = false;
  120. p.gridview = true;
  121. if (p.rowTotal === null) { p.rowNum = p.maxRowNum; }
  122. p.rowList = [];
  123. //pico = "ui-icon-triangle-1-" + (p.direction==="rtl" ? "w" : "e");
  124. //p.treeIcons = $.extend({plus:pico,minus:"ui-icon-triangle-1-s",leaf:"ui-icon-radio-off"},p.treeIcons || {});
  125. p.treeIcons.plus = p.direction === "rtl" ? p.treeIcons.plusRtl : p.treeIcons.plusLtr;
  126. if (p.treeGridModel === "nested") {
  127. p.treeReader = $.extend({
  128. level_field: "level",
  129. left_field: "lft",
  130. right_field: "rgt",
  131. leaf_field: "isLeaf",
  132. expanded_field: "expanded",
  133. loaded: "loaded",
  134. icon_field: "icon"
  135. }, p.treeReader);
  136. } else if (p.treeGridModel === "adjacency") {
  137. p.treeReader = $.extend({
  138. level_field: "level",
  139. parent_id_field: "parent",
  140. leaf_field: "isLeaf",
  141. expanded_field: "expanded",
  142. loaded: "loaded",
  143. icon_field: "icon"
  144. }, p.treeReader);
  145. }
  146. for (key in p.colModel) {
  147. if (p.colModel.hasOwnProperty(key)) {
  148. nm = p.colModel[key].name;
  149. for (tkey in p.treeReader) {
  150. if (p.treeReader.hasOwnProperty(tkey) && p.treeReader[tkey] === nm) {
  151. dupcols.push(nm);
  152. }
  153. }
  154. }
  155. }
  156. $.each(p.treeReader, function (prop) {
  157. var name = String(this);
  158. if (name && $.inArray(name, dupcols) === -1) {
  159. if ($.inArray(prop, boolProp) >= 0) {
  160. p.additionalProperties.push({
  161. name: name,
  162. search: false,
  163. convert: function (data) {
  164. return data === true || String(data).toLowerCase() === "true" || String(data) === "1" ? true : data;
  165. }
  166. });
  167. } else {
  168. p.additionalProperties.push(name);
  169. }
  170. }
  171. });
  172. });
  173. },
  174. expandRow: function (record) {
  175. this.each(function () {
  176. var $t = this, $self = $($t), p = $t.p;
  177. if (!$t.grid || !p.treeGrid) { return; }
  178. var expanded = p.treeReader.expanded_field, rowid = record[p.localReader.id]; // without prefix
  179. if (!treeGridFeedback.call($t, "beforeExpandRow", { rowid: rowid, item: record })) { return; }
  180. var childern = base.getNodeChildren.call($self, record);
  181. $(childern).each(function () {
  182. var id = p.idPrefix + getAccessor(this, p.localReader.id);
  183. $(base.getGridRowById.call($self, id)).css("display", "");
  184. if (this[expanded]) {
  185. base.expandRow.call($self, this);
  186. }
  187. });
  188. treeGridFeedback.call($t, "afterExpandRow", { rowid: rowid, item: record });
  189. });
  190. },
  191. collapseRow: function (record) {
  192. this.each(function () {
  193. var $t = this, $self = $($t), p = $t.p;
  194. if (!$t.grid || !p.treeGrid) { return; }
  195. var expanded = p.treeReader.expanded_field, rowid = record[p.localReader.id]; // without prefix
  196. if (!treeGridFeedback.call($t, "beforeCollapseRow", { rowid: rowid, item: record })) { return; }
  197. var childern = base.getNodeChildren.call($self, record);
  198. $(childern).each(function () {
  199. var id = p.idPrefix + getAccessor(this, p.localReader.id);
  200. $(base.getGridRowById.call($self, id)).css("display", "none");
  201. if (this[expanded]) {
  202. base.collapseRow.call($self, this);
  203. }
  204. });
  205. treeGridFeedback.call($t, "afterCollapseRow", { rowid: rowid, item: record });
  206. });
  207. },
  208. // NS ,adjacency models
  209. getRootNodes: function () {
  210. var result = [];
  211. this.each(function () {
  212. var $t = this, p = $t.p;
  213. if (!$t.grid || !p.treeGrid) { return; }
  214. switch (p.treeGridModel) {
  215. case "nested":
  216. var level = p.treeReader.level_field;
  217. $(p.data).each(function () {
  218. if (parseInt(this[level], 10) === parseInt(p.tree_root_level, 10)) {
  219. result.push(this);
  220. }
  221. });
  222. break;
  223. case "adjacency":
  224. var parentId = p.treeReader.parent_id_field;
  225. $(p.data).each(function () {
  226. if (this[parentId] === null || String(this[parentId]).toLowerCase() === "null") {
  227. result.push(this);
  228. }
  229. });
  230. break;
  231. }
  232. });
  233. return result;
  234. },
  235. getNodeDepth: function (rc) {
  236. var ret = null;
  237. this.each(function () {
  238. var $t = this, p = $t.p;
  239. if (!$t.grid || !p.treeGrid) { return; }
  240. switch (p.treeGridModel) {
  241. case "nested":
  242. var level = p.treeReader.level_field;
  243. ret = parseInt(rc[level], 10) - parseInt(p.tree_root_level, 10);
  244. break;
  245. case "adjacency":
  246. ret = base.getNodeAncestors.call($($t), rc).length;
  247. break;
  248. }
  249. });
  250. return ret;
  251. },
  252. getNodeParent: function (rc) {
  253. // var $t = this instanceof $ && this.length > 0 ? this[0] : this;
  254. var $t = this[0];
  255. if (!$t || !$t.grid || $t.p == null || !$t.p.treeGrid || rc == null) { return null; }
  256. var p = $t.p, treeReader = p.treeReader, parentIdName = treeReader.parent_id_field, parentId = rc[parentIdName];
  257. if (p.treeGridModel === "nested") {
  258. var result = null,
  259. lftc = treeReader.left_field,
  260. rgtc = treeReader.right_field,
  261. levelc = treeReader.level_field,
  262. lft = parseInt(rc[lftc], 10), rgt = parseInt(rc[rgtc], 10), level = parseInt(rc[levelc], 10);
  263. $(p.data).each(function () {
  264. if (parseInt(this[levelc], 10) === level - 1 && parseInt(this[lftc], 10) < lft && parseInt(this[rgtc], 10) > rgt) {
  265. result = this;
  266. return false;
  267. }
  268. });
  269. return result;
  270. }
  271. if (parentId === null || parentId === "null") { return null; }
  272. var iParent = p._index[parentId];
  273. return iParent !== undefined ? p.data[iParent] : null;
  274. },
  275. getNodeChildren: function (rc) {
  276. var result = [];
  277. this.each(function () {
  278. var $t = this, p = $t.p;
  279. if (!$t.grid || !p.treeGrid) { return; }
  280. switch (p.treeGridModel) {
  281. case "nested":
  282. var lftc = p.treeReader.left_field, rgtc = p.treeReader.right_field, levelc = p.treeReader.level_field,
  283. lft = parseInt(rc[lftc], 10),
  284. rgt = parseInt(rc[rgtc], 10),
  285. level = parseInt(rc[levelc], 10);
  286. $(p.data).each(function () {
  287. if (parseInt(this[levelc], 10) === level + 1 && parseInt(this[lftc], 10) > lft && parseInt(this[rgtc], 10) < rgt) {
  288. result.push(this);
  289. }
  290. });
  291. break;
  292. case "adjacency":
  293. var parentId = p.treeReader.parent_id_field, dtid = p.localReader.id;
  294. $(p.data).each(function () {
  295. if (String(this[parentId]) === String(rc[dtid])) {
  296. result.push(this);
  297. }
  298. });
  299. break;
  300. }
  301. });
  302. return result;
  303. },
  304. getFullTreeNode: function (rc) {
  305. var result = [];
  306. this.each(function () {
  307. var $t = this, p = $t.p, len;
  308. if (!$t.grid || !p.treeGrid) { return; }
  309. switch (p.treeGridModel) {
  310. case "nested":
  311. var lftc = p.treeReader.left_field, rgtc = p.treeReader.right_field, levelc = p.treeReader.level_field,
  312. lft = parseInt(rc[lftc], 10),
  313. rgt = parseInt(rc[rgtc], 10),
  314. level = parseInt(rc[levelc], 10);
  315. $(p.data).each(function () {
  316. if (parseInt(this[levelc], 10) >= level && parseInt(this[lftc], 10) >= lft && parseInt(this[lftc], 10) <= rgt) {
  317. result.push(this);
  318. }
  319. });
  320. break;
  321. case "adjacency":
  322. if (rc) {
  323. result.push(rc);
  324. var parentId = p.treeReader.parent_id_field, dtid = p.localReader.id;
  325. $(p.data).each(function () {
  326. var i;
  327. len = result.length;
  328. for (i = 0; i < len; i++) {
  329. if (String(result[i][dtid]) === String(this[parentId])) {
  330. result.push(this);
  331. break;
  332. }
  333. }
  334. });
  335. }
  336. break;
  337. }
  338. });
  339. return result;
  340. },
  341. // End NS, adjacency Model
  342. getNodeAncestors: function (rc) {
  343. var ancestors = [];
  344. this.each(function () {
  345. var $t = this, $self = $($t), getNodeParent = base.getNodeParent;
  346. if (!$t.grid || !$t.p.treeGrid) { return; }
  347. var parent = getNodeParent.call($self, rc);
  348. while (parent) {
  349. ancestors.push(parent);
  350. parent = getNodeParent.call($self, parent);
  351. }
  352. });
  353. return ancestors;
  354. },
  355. isVisibleNode: function (rc) {
  356. var result = true;
  357. this.each(function () {
  358. var $t = this, p = $t.p;
  359. if (!$t.grid || !p.treeGrid) { return; }
  360. var ancestors = base.getNodeAncestors.call($($t), rc), expanded = p.treeReader.expanded_field;
  361. $(ancestors).each(function () {
  362. result = result && this[expanded];
  363. if (!result) { return false; }
  364. });
  365. });
  366. return result;
  367. },
  368. isNodeLoaded: function (rc) {
  369. var result;
  370. this.each(function () {
  371. var $t = this, p = $t.p;
  372. if (!$t.grid || !p.treeGrid) { return; }
  373. var isLeaf = p.treeReader.leaf_field, loaded = p.treeReader.loaded;
  374. if (rc !== undefined) {
  375. if (rc[loaded] !== undefined) {
  376. result = rc[loaded];
  377. } else if (rc[isLeaf] || base.getNodeChildren.call($($t), rc).length > 0) {
  378. result = true;
  379. } else {
  380. result = false;
  381. }
  382. } else {
  383. result = false;
  384. }
  385. });
  386. return result;
  387. },
  388. expandNode: function (rc) {
  389. return this.each(function () {
  390. var $t = this, p = $t.p, id, rc1, icons;
  391. if (!$t.grid || !p.treeGrid) { return; }
  392. var treeReader = p.treeReader;
  393. if (!rc[treeReader.expanded_field]) {
  394. id = getAccessor(rc, p.localReader.id);
  395. if (!treeGridFeedback.call($t, "beforeExpandNode", { rowid: id, item: rc })) { return; }
  396. rc1 = $("#" + p.idPrefix + jqID(id), $t.grid.bDiv)[0];
  397. rc[treeReader.expanded_field] = true;
  398. icons = getNodeIcons(p, rc);
  399. $("div.treeclick", rc1).removeClass(icons.collapsed).addClass(icons.common).addClass(icons.expanded);
  400. if (p.treedatatype !== "local" && !base.isNodeLoaded.call($($t), p.data[p._index[id]]) && !$t.grid.hDiv.loading) {
  401. // set the value which will be used during processing of the server response
  402. // in readInput
  403. p.treeANode = rc1.rowIndex;
  404. p.datatype = p.treedatatype;
  405. base.setGridParam.call($($t), {
  406. postData: p.treeGridModel === "nested" ?
  407. {
  408. nodeid: id,
  409. n_level: rc[treeReader.level_field],
  410. n_left: rc[treeReader.left_field],
  411. n_right: rc[treeReader.right_field]
  412. } :
  413. {
  414. nodeid: id,
  415. n_level: rc[treeReader.level_field],
  416. parentid: rc[treeReader.parent_id_field]
  417. }
  418. });
  419. $($t).trigger("reloadGrid");
  420. rc[treeReader.loaded] = true;
  421. base.setGridParam.call($($t), {
  422. postData: p.treeGridModel === "nested" ?
  423. {
  424. nodeid: "",
  425. n_level: "",
  426. n_left: "",
  427. n_right: ""
  428. } :
  429. {
  430. nodeid: "",
  431. n_level: "",
  432. parentid: ""
  433. }
  434. });
  435. }
  436. treeGridFeedback.call($t, "afterExpandNode", { rowid: id, item: rc });
  437. }
  438. });
  439. },
  440. collapseNode: function (rc) {
  441. return this.each(function () {
  442. var $t = this, p = $t.p, icons;
  443. if (!$t.grid || !p.treeGrid) { return; }
  444. var expanded = p.treeReader.expanded_field;
  445. if (rc[expanded]) {
  446. var id = getAccessor(rc, p.localReader.id);
  447. if (!treeGridFeedback.call($t, "beforeCollapseNode", { rowid: id, item: rc })) { return; }
  448. rc[expanded] = false;
  449. icons = getNodeIcons(p, rc);
  450. $("#" + p.idPrefix + jqID(id), $t.grid.bDiv) // $tr
  451. .find("div.treeclick")
  452. .removeClass(icons.expanded)
  453. .addClass(icons.common)
  454. .addClass(icons.collapsed);
  455. if (p.unloadNodeOnCollapse === true || ($.isFunction(p.unloadNodeOnCollapse) && p.unloadNodeOnCollapse.call($t, rc))) {
  456. rc[p.treeReader.loaded] = false;
  457. $($t).jqGrid("delTreeNode", id, true);
  458. }
  459. treeGridFeedback.call($t, "afterCollapseNode", { rowid: id, item: rc });
  460. }
  461. });
  462. },
  463. SortTree: function (sortname, newDir, st, datefmt) {
  464. return this.each(function () {
  465. var $t = this, p = $t.p, $self = $($t);
  466. if (!$t.grid || !p.treeGrid) { return; }
  467. var i, len, rec, records = [], rt = base.getRootNodes.call($self), query = jgrid.from.call($t, rt);
  468. // Sorting roots
  469. query.orderBy(sortname, newDir, st, datefmt);
  470. var roots = query.select();
  471. // Sorting children
  472. for (i = 0, len = roots.length; i < len; i++) {
  473. rec = roots[i];
  474. records.push(rec);
  475. base.collectChildrenSortTree.call($self, records, rec, sortname, newDir, st, datefmt);
  476. }
  477. $.each(records, function (index) {
  478. var id = getAccessor(this, p.localReader.id);
  479. $($t.rows[index]).after($self.find(">tbody>tr#" + jqID(id)));
  480. });
  481. });
  482. },
  483. collectChildrenSortTree: function (records, rec, sortname, newDir, st, datefmt) {
  484. return this.each(function () {
  485. var $t = this, $self = $($t);
  486. if (!$t.grid || !$t.p.treeGrid) { return; }
  487. var i, len, child, ch = base.getNodeChildren.call($self, rec), query = jgrid.from.call($t, ch);
  488. query.orderBy(sortname, newDir, st, datefmt);
  489. var children = query.select();
  490. for (i = 0, len = children.length; i < len; i++) {
  491. child = children[i];
  492. records.push(child);
  493. base.collectChildrenSortTree.call($self, records, child, sortname, newDir, st, datefmt);
  494. }
  495. });
  496. },
  497. // experimental
  498. setTreeRow: function (rowid, data) {
  499. var success = false;
  500. this.each(function () {
  501. var t = this;
  502. if (!t.grid || !t.p.treeGrid) { return; }
  503. success = base.setRowData.call($(t), rowid, data);
  504. });
  505. return success;
  506. },
  507. delTreeNode: function (rowid, skipSelf) {
  508. return this.each(function () {
  509. var $t = this, p = $t.p, myright, width, res, key, rid = p.localReader.id, i, $self = $($t),
  510. left = p.treeReader.left_field,
  511. right = p.treeReader.right_field;
  512. if (!$t.grid || !p.treeGrid) { return; }
  513. var rc = p._index[rowid];
  514. if (rc !== undefined) {
  515. // nested
  516. myright = parseInt(p.data[rc][right], 10);
  517. width = myright - parseInt(p.data[rc][left], 10) + 1;
  518. var dr = base.getFullTreeNode.call($self, p.data[rc]);
  519. if (dr.length > 0) {
  520. for (i = 0; i < dr.length; i++) {
  521. if (!skipSelf || rowid !== dr[i][rid]) {
  522. base.delRowData.call($self, dr[i][rid]);
  523. }
  524. }
  525. }
  526. if (p.treeGridModel === "nested") {
  527. // ToDo - update grid data
  528. res = jgrid.from.call($t, p.data)
  529. .greater(left, myright, { stype: "integer" })
  530. .select();
  531. if (res.length) {
  532. for (key in res) {
  533. if (res.hasOwnProperty(key)) {
  534. res[key][left] = parseInt(res[key][left], 10) - width;
  535. }
  536. }
  537. }
  538. res = jgrid.from.call($t, p.data)
  539. .greater(right, myright, { stype: "integer" })
  540. .select();
  541. if (res.length) {
  542. for (key in res) {
  543. if (res.hasOwnProperty(key)) {
  544. res[key][right] = parseInt(res[key][right], 10) - width;
  545. }
  546. }
  547. }
  548. }
  549. }
  550. });
  551. },
  552. addChildNode: function (nodeid, parentid, data, expandData) {
  553. return this.each(function () {
  554. if (!data) { return; }
  555. var $t = this, p = $t.p, $self = $($t), getInd = base.getInd,
  556. iconExpanded = p.treeIcons.minus + " tree-minus",
  557. method, parentindex, parentdata, parentlevel, iRow, rowind = parentid, leaf, maxright,
  558. expanded = p.treeReader.expanded_field, isLeaf = p.treeReader.leaf_field, level = p.treeReader.level_field,
  559. parent = p.treeReader.parent_id_field,
  560. left = p.treeReader.left_field,
  561. right = p.treeReader.right_field,
  562. loaded = p.treeReader.loaded;
  563. if (expandData === undefined) { expandData = false; }
  564. if (nodeid == null) {
  565. nodeid = jgrid.randId();
  566. }
  567. var prow = getInd.call($self, parentid);
  568. leaf = false;
  569. // if not a parent we assume root
  570. if (parentid === undefined || parentid === null || parentid === "") {
  571. parentid = null;
  572. rowind = null;
  573. method = "last";
  574. parentlevel = p.tree_root_level;
  575. } else {
  576. method = "after";
  577. parentindex = p._index[parentid];
  578. parentdata = p.data[parentindex];
  579. parentid = parentdata[p.localReader.id];
  580. iRow = getInd.call($self, parentid);
  581. parentlevel = parseInt(parentdata[level], 10) + 1;
  582. var childs = base.getFullTreeNode.call($self, parentdata);
  583. // if there are child nodes get the last index of it
  584. if (childs.length) {
  585. // find the max rowIndex of the children
  586. var iChild, iChildRow, childId;
  587. for (iChild = 0; iChild < childs.length; iChild++) {
  588. childId = childs[iChild][p.localReader.id];
  589. iChildRow = getInd.call($self, childId);
  590. if (iChildRow > iRow) {
  591. iRow = iChildRow;
  592. rowind = childId;
  593. }
  594. }
  595. }
  596. // if the node is leaf
  597. if (parentdata[isLeaf]) {
  598. leaf = true;
  599. parentdata[expanded] = true;
  600. //var prow = getInd.call($self, parentid);
  601. $($t.rows[prow])
  602. .find("span.cell-wrapperleaf").removeClass("cell-wrapperleaf").addClass("cell-wrapper")
  603. .end()
  604. .find("div.tree-leaf").removeClass(p.treeIcons.leaf + " tree-leaf").addClass(p.treeIcons.commonIconClass).addClass(iconExpanded);
  605. p.data[parentindex][isLeaf] = false;
  606. parentdata[loaded] = true;
  607. }
  608. }
  609. if (data[expanded] === undefined) { data[expanded] = false; }
  610. if (data[loaded] === undefined) { data[loaded] = false; }
  611. data[level] = parentlevel;
  612. if (data[isLeaf] === undefined) { data[isLeaf] = true; }
  613. if (p.treeGridModel === "adjacency") {
  614. data[parent] = parentid;
  615. }
  616. if (p.treeGridModel === "nested") {
  617. // this method requiere more attention
  618. var query, res, key;
  619. //maxright = parseInt(maxright,10);
  620. // ToDo - update grid data
  621. if (parentid !== null) {
  622. maxright = parseInt(parentdata[right], 10);
  623. query = jgrid.from.call($t, p.data);
  624. query = query.greaterOrEquals(right, maxright, { stype: "integer" });
  625. res = query.select();
  626. if (res.length) {
  627. for (key in res) {
  628. if (res.hasOwnProperty(key)) {
  629. res[key][left] = res[key][left] > maxright ? parseInt(res[key][left], 10) + 2 : res[key][left];
  630. res[key][right] = res[key][right] >= maxright ? parseInt(res[key][right], 10) + 2 : res[key][right];
  631. }
  632. }
  633. }
  634. data[left] = maxright;
  635. data[right] = maxright + 1;
  636. } else {
  637. maxright = parseInt(base.getCol.call($self, right, false, "max"), 10);
  638. res = jgrid.from.call($t, p.data)
  639. .greater(left, maxright, { stype: "integer" })
  640. .select();
  641. if (res.length) {
  642. for (key in res) {
  643. if (res.hasOwnProperty(key)) {
  644. res[key][left] = parseInt(res[key][left], 10) + 2;
  645. }
  646. }
  647. }
  648. res = jgrid.from.call($t, p.data)
  649. .greater(right, maxright, { stype: "integer" })
  650. .select();
  651. if (res.length) {
  652. for (key in res) {
  653. if (res.hasOwnProperty(key)) {
  654. res[key][right] = parseInt(res[key][right], 10) + 2;
  655. }
  656. }
  657. }
  658. data[left] = maxright + 1;
  659. data[right] = maxright + 2;
  660. }
  661. }
  662. if (parentid === null || base.isNodeLoaded.call($self, parentdata) || leaf) {
  663. base.addRowData.call($self, nodeid, data, method, rowind);
  664. }
  665. if (parentdata && !parentdata[expanded] && expandData) {
  666. $($t.rows[prow])
  667. .find("div.treeclick")
  668. .click();
  669. }
  670. });
  671. }
  672. });
  673. // end module grid.treegrid
  674. }));