template.js.plugins.grid.treegrid.js Maven / Gradle / Ivy
/**
* jqGrid extension - Tree Grid
* Copyright (c) 2008-2014, Tony Tomov, [email protected]
* Copyright (c) 2014-2018, Oleg Kiriljuk, [email protected]
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl-2.0.html
**/
/*jshint eqeqeq:false */
/*jslint browser: true, eqeq: true, plusplus: true, nomen: true, unparam: true, vars: true, white: true, todo: true */
/*global jQuery, define, exports, module, require */
(function (factory) {
"use strict";
if (typeof define === "function" && define.amd) {
// AMD. Register as an anonymous module.
define([
"jquery",
"./grid.base"
], factory);
} else if (typeof module === "object" && module.exports) {
// Node/CommonJS
module.exports = function (root, $) {
if (!root) {
root = window;
}
if ($ === undefined) {
// require("jquery") returns a factory that requires window to
// build a jQuery instance, we normalize how we use modules
// that require this pattern but the window provided is a noop
// if it's defined (how jquery works)
$ = typeof window !== "undefined" ?
require("jquery") :
require("jquery")(root);
}
require("./grid.base");
factory($);
return $;
};
} else {
// Browser globals
factory(jQuery);
}
}(function ($) {
"use strict";
var jgrid = $.jgrid, getAccessor = jgrid.getAccessor, stripPref = jgrid.stripPref,
jqID = jgrid.jqID, base = $.fn.jqGrid;
// begin module grid.treegrid
var treeGridFeedback = function () {
var args = $.makeArray(arguments);
args[0] = "treeGrid" + args[0].charAt(0).toUpperCase() + args[0].substring(1);
args.unshift("");
args.unshift("");
args.unshift(this.p);
return jgrid.feedback.apply(this, args);
},
getNodeIcons = function (p, item) {
var icons = item[p.treeReader.icon_field],
treeIcons = p.treeIcons,
iconCollapsed = treeIcons.plus + " tree-plus",
iconExpanded = treeIcons.minus + " tree-minus";
if (icons && typeof icons === "string") {
icons = icons.split(",");
if (icons.length === 2) {
iconExpanded = icons[0];
iconCollapsed = icons[1];
}
}
return {
expanded: iconExpanded,
collapsed: iconCollapsed,
common: treeIcons.commonIconClass
};
};
jgrid.extend({
setTreeNode: function () {
// TODO: Move the code in setTreeGrid because it uses currently no parameters
// and it's don't make any actions with specific row
return this.each(function () {
var $t = this, $self = $($t), p = $t.p;
if (!$t.grid || !p.treeGrid) { return; }
var expanded = p.treeReader.expanded_field,
isLeaf = p.treeReader.leaf_field,
beforeSelectRow = function (e, rowid, eOrg) {
if (eOrg != null) {
var $target = $(eOrg.target),
$td = $target.closest("tr.jqgrow>td"),
$tr = $td.parent(),
expendOrCollaps = function () {
var item = p.data[p._index[stripPref(p.idPrefix, rowid)]],
collapseOrExpand = item[expanded] ? "collapse" : "expand";
if (!item[isLeaf]) {
base[collapseOrExpand + "Row"].call($self, item, $tr);
base[collapseOrExpand + "Node"].call($self, item, $tr);
}
};
if ($target.is("div.treeclick")) {
expendOrCollaps();
} else if (p.ExpandColClick) {
if ($td.length > 0 && $target.closest("span.cell-wrapper", $td).length > 0) {
expendOrCollaps();
}
}
return true; // allow selection
}
};
$self.off("jqGridBeforeSelectRow.setTreeNode");
$self.on("jqGridBeforeSelectRow.setTreeNode", beforeSelectRow);
});
},
setTreeGrid: function () {
return this.each(function () {
var $t = this, p = $t.p, nm, key, tkey, dupcols = [],
boolProp = ["leaf_field", "expanded_field", "loaded"];
if (!p.treeGrid) { return; }
if (!p.treedatatype) { $.extend($t.p, { treedatatype: p.datatype }); }
p.subGrid = false;
p.altRows = false;
p.pgbuttons = false;
p.pginput = false;
p.gridview = true;
if (p.rowTotal === null) { p.rowNum = p.maxRowNum; }
p.rowList = [];
//pico = "ui-icon-triangle-1-" + (p.direction==="rtl" ? "w" : "e");
//p.treeIcons = $.extend({plus:pico,minus:"ui-icon-triangle-1-s",leaf:"ui-icon-radio-off"},p.treeIcons || {});
p.treeIcons.plus = p.direction === "rtl" ? p.treeIcons.plusRtl : p.treeIcons.plusLtr;
if (p.treeGridModel === "nested") {
p.treeReader = $.extend({
level_field: "level",
left_field: "lft",
right_field: "rgt",
leaf_field: "isLeaf",
expanded_field: "expanded",
loaded: "loaded",
icon_field: "icon"
}, p.treeReader);
} else if (p.treeGridModel === "adjacency") {
p.treeReader = $.extend({
level_field: "level",
parent_id_field: "parent",
leaf_field: "isLeaf",
expanded_field: "expanded",
loaded: "loaded",
icon_field: "icon"
}, p.treeReader);
}
for (key in p.colModel) {
if (p.colModel.hasOwnProperty(key)) {
nm = p.colModel[key].name;
for (tkey in p.treeReader) {
if (p.treeReader.hasOwnProperty(tkey) && p.treeReader[tkey] === nm) {
dupcols.push(nm);
}
}
}
}
$.each(p.treeReader, function (prop) {
var name = String(this);
if (name && $.inArray(name, dupcols) === -1) {
if ($.inArray(prop, boolProp) >= 0) {
p.additionalProperties.push({
name: name,
search: false,
convert: function (data) {
return data === true || String(data).toLowerCase() === "true" || String(data) === "1" ? true : data;
}
});
} else {
p.additionalProperties.push(name);
}
}
});
});
},
expandRow: function (record) {
this.each(function () {
var $t = this, $self = $($t), p = $t.p;
if (!$t.grid || !p.treeGrid) { return; }
var expanded = p.treeReader.expanded_field, rowid = record[p.localReader.id]; // without prefix
if (!treeGridFeedback.call($t, "beforeExpandRow", { rowid: rowid, item: record })) { return; }
var childern = base.getNodeChildren.call($self, record);
$(childern).each(function () {
var id = p.idPrefix + getAccessor(this, p.localReader.id);
$(base.getGridRowById.call($self, id)).css("display", "");
if (this[expanded]) {
base.expandRow.call($self, this);
}
});
treeGridFeedback.call($t, "afterExpandRow", { rowid: rowid, item: record });
});
},
collapseRow: function (record) {
this.each(function () {
var $t = this, $self = $($t), p = $t.p;
if (!$t.grid || !p.treeGrid) { return; }
var expanded = p.treeReader.expanded_field, rowid = record[p.localReader.id]; // without prefix
if (!treeGridFeedback.call($t, "beforeCollapseRow", { rowid: rowid, item: record })) { return; }
var childern = base.getNodeChildren.call($self, record);
$(childern).each(function () {
var id = p.idPrefix + getAccessor(this, p.localReader.id);
$(base.getGridRowById.call($self, id)).css("display", "none");
if (this[expanded]) {
base.collapseRow.call($self, this);
}
});
treeGridFeedback.call($t, "afterCollapseRow", { rowid: rowid, item: record });
});
},
// NS ,adjacency models
getRootNodes: function () {
var result = [];
this.each(function () {
var $t = this, p = $t.p;
if (!$t.grid || !p.treeGrid) { return; }
switch (p.treeGridModel) {
case "nested":
var level = p.treeReader.level_field;
$(p.data).each(function () {
if (parseInt(this[level], 10) === parseInt(p.tree_root_level, 10)) {
result.push(this);
}
});
break;
case "adjacency":
var parentId = p.treeReader.parent_id_field;
$(p.data).each(function () {
if (this[parentId] === null || String(this[parentId]).toLowerCase() === "null") {
result.push(this);
}
});
break;
}
});
return result;
},
getNodeDepth: function (rc) {
var ret = null;
this.each(function () {
var $t = this, p = $t.p;
if (!$t.grid || !p.treeGrid) { return; }
switch (p.treeGridModel) {
case "nested":
var level = p.treeReader.level_field;
ret = parseInt(rc[level], 10) - parseInt(p.tree_root_level, 10);
break;
case "adjacency":
ret = base.getNodeAncestors.call($($t), rc).length;
break;
}
});
return ret;
},
getNodeParent: function (rc) {
// var $t = this instanceof $ && this.length > 0 ? this[0] : this;
var $t = this[0];
if (!$t || !$t.grid || $t.p == null || !$t.p.treeGrid || rc == null) { return null; }
var p = $t.p, treeReader = p.treeReader, parentIdName = treeReader.parent_id_field, parentId = rc[parentIdName];
if (p.treeGridModel === "nested") {
var result = null,
lftc = treeReader.left_field,
rgtc = treeReader.right_field,
levelc = treeReader.level_field,
lft = parseInt(rc[lftc], 10), rgt = parseInt(rc[rgtc], 10), level = parseInt(rc[levelc], 10);
$(p.data).each(function () {
if (parseInt(this[levelc], 10) === level - 1 && parseInt(this[lftc], 10) < lft && parseInt(this[rgtc], 10) > rgt) {
result = this;
return false;
}
});
return result;
}
if (parentId === null || parentId === "null") { return null; }
var iParent = p._index[parentId];
return iParent !== undefined ? p.data[iParent] : null;
},
getNodeChildren: function (rc) {
var result = [];
this.each(function () {
var $t = this, p = $t.p;
if (!$t.grid || !p.treeGrid) { return; }
switch (p.treeGridModel) {
case "nested":
var lftc = p.treeReader.left_field, rgtc = p.treeReader.right_field, levelc = p.treeReader.level_field,
lft = parseInt(rc[lftc], 10),
rgt = parseInt(rc[rgtc], 10),
level = parseInt(rc[levelc], 10);
$(p.data).each(function () {
if (parseInt(this[levelc], 10) === level + 1 && parseInt(this[lftc], 10) > lft && parseInt(this[rgtc], 10) < rgt) {
result.push(this);
}
});
break;
case "adjacency":
var parentId = p.treeReader.parent_id_field, dtid = p.localReader.id;
$(p.data).each(function () {
if (String(this[parentId]) === String(rc[dtid])) {
result.push(this);
}
});
break;
}
});
return result;
},
getFullTreeNode: function (rc) {
var result = [];
this.each(function () {
var $t = this, p = $t.p, len;
if (!$t.grid || !p.treeGrid) { return; }
switch (p.treeGridModel) {
case "nested":
var lftc = p.treeReader.left_field, rgtc = p.treeReader.right_field, levelc = p.treeReader.level_field,
lft = parseInt(rc[lftc], 10),
rgt = parseInt(rc[rgtc], 10),
level = parseInt(rc[levelc], 10);
$(p.data).each(function () {
if (parseInt(this[levelc], 10) >= level && parseInt(this[lftc], 10) >= lft && parseInt(this[lftc], 10) <= rgt) {
result.push(this);
}
});
break;
case "adjacency":
if (rc) {
result.push(rc);
var parentId = p.treeReader.parent_id_field, dtid = p.localReader.id;
$(p.data).each(function () {
var i;
len = result.length;
for (i = 0; i < len; i++) {
if (String(result[i][dtid]) === String(this[parentId])) {
result.push(this);
break;
}
}
});
}
break;
}
});
return result;
},
// End NS, adjacency Model
getNodeAncestors: function (rc) {
var ancestors = [];
this.each(function () {
var $t = this, $self = $($t), getNodeParent = base.getNodeParent;
if (!$t.grid || !$t.p.treeGrid) { return; }
var parent = getNodeParent.call($self, rc);
while (parent) {
ancestors.push(parent);
parent = getNodeParent.call($self, parent);
}
});
return ancestors;
},
isVisibleNode: function (rc) {
var result = true;
this.each(function () {
var $t = this, p = $t.p;
if (!$t.grid || !p.treeGrid) { return; }
var ancestors = base.getNodeAncestors.call($($t), rc), expanded = p.treeReader.expanded_field;
$(ancestors).each(function () {
result = result && this[expanded];
if (!result) { return false; }
});
});
return result;
},
isNodeLoaded: function (rc) {
var result;
this.each(function () {
var $t = this, p = $t.p;
if (!$t.grid || !p.treeGrid) { return; }
var isLeaf = p.treeReader.leaf_field, loaded = p.treeReader.loaded;
if (rc !== undefined) {
if (rc[loaded] !== undefined) {
result = rc[loaded];
} else if (rc[isLeaf] || base.getNodeChildren.call($($t), rc).length > 0) {
result = true;
} else {
result = false;
}
} else {
result = false;
}
});
return result;
},
expandNode: function (rc) {
return this.each(function () {
var $t = this, p = $t.p, id, rc1, icons;
if (!$t.grid || !p.treeGrid) { return; }
var treeReader = p.treeReader;
if (!rc[treeReader.expanded_field]) {
id = getAccessor(rc, p.localReader.id);
if (!treeGridFeedback.call($t, "beforeExpandNode", { rowid: id, item: rc })) { return; }
rc1 = $("#" + p.idPrefix + jqID(id), $t.grid.bDiv)[0];
rc[treeReader.expanded_field] = true;
icons = getNodeIcons(p, rc);
$("div.treeclick", rc1).removeClass(icons.collapsed).addClass(icons.common).addClass(icons.expanded);
if (p.treedatatype !== "local" && !base.isNodeLoaded.call($($t), p.data[p._index[id]]) && !$t.grid.hDiv.loading) {
// set the value which will be used during processing of the server response
// in readInput
p.treeANode = rc1.rowIndex;
p.datatype = p.treedatatype;
base.setGridParam.call($($t), {
postData: p.treeGridModel === "nested" ?
{
nodeid: id,
n_level: rc[treeReader.level_field],
n_left: rc[treeReader.left_field],
n_right: rc[treeReader.right_field]
} :
{
nodeid: id,
n_level: rc[treeReader.level_field],
parentid: rc[treeReader.parent_id_field]
}
});
$($t).trigger("reloadGrid");
rc[treeReader.loaded] = true;
base.setGridParam.call($($t), {
postData: p.treeGridModel === "nested" ?
{
nodeid: "",
n_level: "",
n_left: "",
n_right: ""
} :
{
nodeid: "",
n_level: "",
parentid: ""
}
});
}
treeGridFeedback.call($t, "afterExpandNode", { rowid: id, item: rc });
}
});
},
collapseNode: function (rc) {
return this.each(function () {
var $t = this, p = $t.p, icons;
if (!$t.grid || !p.treeGrid) { return; }
var expanded = p.treeReader.expanded_field;
if (rc[expanded]) {
var id = getAccessor(rc, p.localReader.id);
if (!treeGridFeedback.call($t, "beforeCollapseNode", { rowid: id, item: rc })) { return; }
rc[expanded] = false;
icons = getNodeIcons(p, rc);
$("#" + p.idPrefix + jqID(id), $t.grid.bDiv) // $tr
.find("div.treeclick")
.removeClass(icons.expanded)
.addClass(icons.common)
.addClass(icons.collapsed);
if (p.unloadNodeOnCollapse === true || ($.isFunction(p.unloadNodeOnCollapse) && p.unloadNodeOnCollapse.call($t, rc))) {
rc[p.treeReader.loaded] = false;
$($t).jqGrid("delTreeNode", id, true);
}
treeGridFeedback.call($t, "afterCollapseNode", { rowid: id, item: rc });
}
});
},
SortTree: function (sortname, newDir, st, datefmt) {
return this.each(function () {
var $t = this, p = $t.p, $self = $($t);
if (!$t.grid || !p.treeGrid) { return; }
var i, len, rec, records = [], rt = base.getRootNodes.call($self), query = jgrid.from.call($t, rt);
// Sorting roots
query.orderBy(sortname, newDir, st, datefmt);
var roots = query.select();
// Sorting children
for (i = 0, len = roots.length; i < len; i++) {
rec = roots[i];
records.push(rec);
base.collectChildrenSortTree.call($self, records, rec, sortname, newDir, st, datefmt);
}
$.each(records, function (index) {
var id = getAccessor(this, p.localReader.id);
$($t.rows[index]).after($self.find(">tbody>tr#" + jqID(id)));
});
});
},
collectChildrenSortTree: function (records, rec, sortname, newDir, st, datefmt) {
return this.each(function () {
var $t = this, $self = $($t);
if (!$t.grid || !$t.p.treeGrid) { return; }
var i, len, child, ch = base.getNodeChildren.call($self, rec), query = jgrid.from.call($t, ch);
query.orderBy(sortname, newDir, st, datefmt);
var children = query.select();
for (i = 0, len = children.length; i < len; i++) {
child = children[i];
records.push(child);
base.collectChildrenSortTree.call($self, records, child, sortname, newDir, st, datefmt);
}
});
},
// experimental
setTreeRow: function (rowid, data) {
var success = false;
this.each(function () {
var t = this;
if (!t.grid || !t.p.treeGrid) { return; }
success = base.setRowData.call($(t), rowid, data);
});
return success;
},
delTreeNode: function (rowid, skipSelf) {
return this.each(function () {
var $t = this, p = $t.p, myright, width, res, key, rid = p.localReader.id, i, $self = $($t),
left = p.treeReader.left_field,
right = p.treeReader.right_field;
if (!$t.grid || !p.treeGrid) { return; }
var rc = p._index[rowid];
if (rc !== undefined) {
// nested
myright = parseInt(p.data[rc][right], 10);
width = myright - parseInt(p.data[rc][left], 10) + 1;
var dr = base.getFullTreeNode.call($self, p.data[rc]);
if (dr.length > 0) {
for (i = 0; i < dr.length; i++) {
if (!skipSelf || rowid !== dr[i][rid]) {
base.delRowData.call($self, dr[i][rid]);
}
}
}
if (p.treeGridModel === "nested") {
// ToDo - update grid data
res = jgrid.from.call($t, p.data)
.greater(left, myright, { stype: "integer" })
.select();
if (res.length) {
for (key in res) {
if (res.hasOwnProperty(key)) {
res[key][left] = parseInt(res[key][left], 10) - width;
}
}
}
res = jgrid.from.call($t, p.data)
.greater(right, myright, { stype: "integer" })
.select();
if (res.length) {
for (key in res) {
if (res.hasOwnProperty(key)) {
res[key][right] = parseInt(res[key][right], 10) - width;
}
}
}
}
}
});
},
addChildNode: function (nodeid, parentid, data, expandData) {
return this.each(function () {
if (!data) { return; }
var $t = this, p = $t.p, $self = $($t), getInd = base.getInd,
iconExpanded = p.treeIcons.minus + " tree-minus",
method, parentindex, parentdata, parentlevel, iRow, rowind = parentid, leaf, maxright,
expanded = p.treeReader.expanded_field, isLeaf = p.treeReader.leaf_field, level = p.treeReader.level_field,
parent = p.treeReader.parent_id_field,
left = p.treeReader.left_field,
right = p.treeReader.right_field,
loaded = p.treeReader.loaded;
if (expandData === undefined) { expandData = false; }
if (nodeid == null) {
nodeid = jgrid.randId();
}
var prow = getInd.call($self, parentid);
leaf = false;
// if not a parent we assume root
if (parentid === undefined || parentid === null || parentid === "") {
parentid = null;
rowind = null;
method = "last";
parentlevel = p.tree_root_level;
} else {
method = "after";
parentindex = p._index[parentid];
parentdata = p.data[parentindex];
parentid = parentdata[p.localReader.id];
iRow = getInd.call($self, parentid);
parentlevel = parseInt(parentdata[level], 10) + 1;
var childs = base.getFullTreeNode.call($self, parentdata);
// if there are child nodes get the last index of it
if (childs.length) {
// find the max rowIndex of the children
var iChild, iChildRow, childId;
for (iChild = 0; iChild < childs.length; iChild++) {
childId = childs[iChild][p.localReader.id];
iChildRow = getInd.call($self, childId);
if (iChildRow > iRow) {
iRow = iChildRow;
rowind = childId;
}
}
}
// if the node is leaf
if (parentdata[isLeaf]) {
leaf = true;
parentdata[expanded] = true;
//var prow = getInd.call($self, parentid);
$($t.rows[prow])
.find("span.cell-wrapperleaf").removeClass("cell-wrapperleaf").addClass("cell-wrapper")
.end()
.find("div.tree-leaf").removeClass(p.treeIcons.leaf + " tree-leaf").addClass(p.treeIcons.commonIconClass).addClass(iconExpanded);
p.data[parentindex][isLeaf] = false;
parentdata[loaded] = true;
}
}
if (data[expanded] === undefined) { data[expanded] = false; }
if (data[loaded] === undefined) { data[loaded] = false; }
data[level] = parentlevel;
if (data[isLeaf] === undefined) { data[isLeaf] = true; }
if (p.treeGridModel === "adjacency") {
data[parent] = parentid;
}
if (p.treeGridModel === "nested") {
// this method requiere more attention
var query, res, key;
//maxright = parseInt(maxright,10);
// ToDo - update grid data
if (parentid !== null) {
maxright = parseInt(parentdata[right], 10);
query = jgrid.from.call($t, p.data);
query = query.greaterOrEquals(right, maxright, { stype: "integer" });
res = query.select();
if (res.length) {
for (key in res) {
if (res.hasOwnProperty(key)) {
res[key][left] = res[key][left] > maxright ? parseInt(res[key][left], 10) + 2 : res[key][left];
res[key][right] = res[key][right] >= maxright ? parseInt(res[key][right], 10) + 2 : res[key][right];
}
}
}
data[left] = maxright;
data[right] = maxright + 1;
} else {
maxright = parseInt(base.getCol.call($self, right, false, "max"), 10);
res = jgrid.from.call($t, p.data)
.greater(left, maxright, { stype: "integer" })
.select();
if (res.length) {
for (key in res) {
if (res.hasOwnProperty(key)) {
res[key][left] = parseInt(res[key][left], 10) + 2;
}
}
}
res = jgrid.from.call($t, p.data)
.greater(right, maxright, { stype: "integer" })
.select();
if (res.length) {
for (key in res) {
if (res.hasOwnProperty(key)) {
res[key][right] = parseInt(res[key][right], 10) + 2;
}
}
}
data[left] = maxright + 1;
data[right] = maxright + 2;
}
}
if (parentid === null || base.isNodeLoaded.call($self, parentdata) || leaf) {
base.addRowData.call($self, nodeid, data, method, rowind);
}
if (parentdata && !parentdata[expanded] && expandData) {
$($t.rows[prow])
.find("div.treeclick")
.click();
}
});
}
});
// end module grid.treegrid
}));
© 2015 - 2025 Weber Informatics LLC | Privacy Policy