1. If you tried to create a tree table, and it didn't work giving an error "cmtypes[st] is undefined" on line 1513 of jquery.jqGrid.src.js:
$(ts).jqGrid("SortTree", st, ts.p.sortorder, cmtypes[st].stype, cmtypes[st].srcfmt);
change this line to the following:
$(ts).jqGrid("SortTree", st, ts.p.sortorder, sorttype, srcformat);
It is working after that.
2. Expanding tree nodes with dynamically loaded local data.
If you create a tree grid with local data, you would notice that even if you don't expand nodes, it still creates hidden rows with this data. This causes a problem of unnecessarily slow loading if you have a lot of data but only want to expand tree nodes on demand, when a user clicks on a node.
First of all, don't load data for hidden rows initially. Second, override the click event. This event in the grid wasn't assigned by the "live" method, but when creating the rows, so we need to change it at the time when loading the data:
grid[0].addJSONData({
...
});
$("div.treeclick").off("click").on("click", onExpand);
The onExpand function will be the following:
var onExpand = function(e) {
var target = e.target || e.srcElement;
var rowid = $(target).closest("tr").attr("id");
var record = grid.getRowData(rowid);
if(record.isLeaf == 'false' || !record.isLeaf) {
if(record.expanded == 'true' || record.expanded == true) {
grid.jqGrid("collapseNode", record);
grid.jqGrid("collapseRow", record);
record['expanded'] = false;
grid.jqGrid("setRowData", rowid, record);
} else {
if(grid.jqGrid("getNodeChildren", record).length > 0) {
grid.jqGrid("expandNode", record);
grid.jqGrid("expandRow", record);
$("tr[id^='"+rowid+"_']").show();
} else {
expand(rowid);
}
record['expanded'] = true;
grid.jqGrid("setRowData", rowid, record);
}
}
return false;
}
"expand" is your function to get new data to expand the node.
Please, note that we manually change the grid row to collapsed and expanded as, unfortunately, jqGrid stores node data in 2 separate places, so the functionality is not very consistent.
When we initially build a node, we don't load it as a leaf because we're going to expand it(the icon wouldn't be a leaf). Unfortunately, jqGrid would go into an infinite clicking cycle (would trigger an event) if we don't make this node a leaf. So, make it temporary a leaf when expanding it! The function (a hack, as jgGrid stores data in 2 different places) is the following:
//hack: set the parent as a leaf to prevent triggering another click
function setLeaf(id, isleaf) {
var record = grid.getRowData(id);
var _index = grid.jqGrid("getGridParam", "_index");
var data = grid.jqGrid("getGridParam", "data");
data[_index[id]]["isLeaf"] = isleaf;
}
Then setting the node data will look the following:
function setNode(rowid, gridData) {
//hack: set the parent as a leaf to prevent triggering another click
function setLeaf(id, isleaf) {
var record = grid.getRowData(id);
var _index = grid.jqGrid("getGridParam", "_index");
var data = grid.jqGrid("getGridParam", "data");
data[_index[id]]["isLeaf"] = isleaf;
}
setLeaf(rowid, true);
gridData.forEach(function(node) {
var notleaf = !node['isLeaf'] || (node['isLeaf'] == 'false');
grid.jqGrid("addChildNode", node["id"], node["parent"], node);
setIcon(node["parent"], true);
var record = grid.getRowData(node["id"]);
if(notleaf) {
record['isLeaf'] = false;
record['expanded'] = false;
grid.setRowData(node["id"], record);
setIcon(node["id"], false, onExpand);
}
});
return false;
}
The last piece will be getting the icons and handlers rights with all the messy business with the leaves-nonleaves. My own settings in jqGrid definition for the tree icons are: triangles for a parent, and no icon for a leaf.
treeIcons: {plus:'ui-icon-triangle-1-e', minus:'ui-icon-triangle-1-s', leaf:'ui-icon-none'}
I had to add my own css for no icon (in the css file):
.ui-icon-none {
background-position: -250px -250px;
}
So my function to get the icons right is the following:
//hack to get the icons right
function setIcon(id, expanded, clickhandler) {
var _index = grid.jqGrid("getGridParam", "_index");
var data = grid.jqGrid("getGridParam", "data");
var $icon = $("tr[id='"+id+"']").find("div.ui-icon");
if(expanded) {
$icon.removeClass("ui-icon-triangle-1-e");
$icon.removeClass("tree-plus");
$icon.addClass("ui-icon-triangle-1-s");
$icon.addClass("tree-minus");
} else {
$icon.removeClass("ui-icon-triangle-1-s");
$icon.removeClass("tree-minus");
$icon.addClass("ui-icon-triangle-1-e");
$icon.addClass("tree-plus");
}
if(clickhandler != undefined) {
$icon.on("click", clickhandler);
}
}
Hopefully, that's it for now!
No comments:
Post a Comment