I\'m trying to get nested subgrids to work using jqGrid with local data. I\'ve searched around quite a bit but haven\'t been able to find a solution. Here is a simplified
I find your question interesting. I think the answer could be helpful for many other people. So I wrote two demos where I demonstrate how the requirements could be implemented.
The first demo are base on the demo from my previous answer (which are based in another one) which code you use already used in the text of your question. I added the trick from the answer additionally to hide the subgrid icon ("+") for the rows which has no subgrids.
To simplify the holding of subgrid data I added in every row subgrid
property which value are the data for the subgrid. The kind of holding the data is very practical because jqGrid save full items of the row so you don't need any hidden columns more. To access to the local data I recommend to use getLocalRow
method. See the answer for example for additional information or the source code of getLocalRow
method which is very simple.
The code of the first demo:
var myData = [
// main grid data
{ id: "m1", col1: "11", col2: "12",
subgrid: [
// data for subgrid for the id=m1
{ id: "s1a", c1: "aa", c2: "ab", c3: "ac",
subgrid: [
// data for subgrid for the id=m1, subgridId=s1a
{ id: "2s1a", d1: "2aa", d2: "2ab", d3: "2ac" },
{ id: "2s1b", d1: "2ba", d2: "2bb", d3: "2bc" },
{ id: "2s1c", d1: "2ca", d2: "2cb", d3: "2cc" }
]},
{ id: "s1b", c1: "ba", c2: "bb", c3: "bc" },
{ id: "s1c", c1: "ca", c2: "cb", c3: "cc" }
]},
{ id: "m2", col1: "21", col2: "22",
subgrid: [
// data for subgrid for the id=m2
{ id: "s2a", c1: "xx", c2: "xy", c3: "xz",
subgrid: [
// data for subgrid for the id=m2, subgridId=s2a
{ id: "2s2a", d1: "xx", d2: "xy", d3: "xz" }
]}
]},
{ id: "m3", col1: "31", col2: "32" }
],
removeSubgridIcon = function () {
var $this = $(this);
$this.find(">tbody>tr.jqgrow>td.ui-sgcollapsed").filter(function () {
var rowData = $this.jqGrid("getLocalRow",
$(this).closest("tr.jqgrow").attr("id"));
return rowData.subgrid == null;
}).unbind("click").html("");
},
isHasSubrids = function (data) {
var l = data.length, i;
for (i = 0; i < l; i++) {
if (data[i].subgrid != null) {
return true;
}
}
return false;
};
$("#list").jqGrid({
datatype: "local",
data: myData,
colNames: ["Column 1", "Column 2"],
colModel: [
{ name: "col1", width: 200 },
{ name: "col2", width: 200 }
],
gridview: true,
rownumbers: true,
autoencode: true,
sortname: "col1",
sortorder: "desc",
height: "100%",
pager: "#pager",
caption: "Demonstrate how to create subgrid from local hierarchical data",
subGrid: isHasSubrids(myData),
loadComplete: function () {
removeSubgridIcon.call(this);
},
subGridRowExpanded: function (subgridDivId1, rowId1) {
var $subgrid1 = $("<table id='" + subgridDivId1 + "_t'></table>"),
localRowData1 = $(this).jqGrid("getLocalRow", rowId1);
$subgrid1.appendTo("#" + $.jgrid.jqID(subgridDivId1));
$subgrid1.jqGrid({
datatype: "local",
data: localRowData1.subgrid,
colNames: ["Colunm1", "Colunm2", "Colunm3"],
colModel: [
{ name: "c1", width: 112 },
{ name: "c2", width: 112 },
{ name: "c3", width: 112 }
],
gridview: true,
rownumbers: true,
autoencode: true,
sortname: "c1",
sortorder: "desc",
height: "100%",
loadComplete: removeSubgridIcon,
subGrid: isHasSubrids(localRowData1.subgrid),
subGridRowExpanded: function (subgridDivId2, rowId2) {
var $subgrid2 = $("<table id='" + subgridDivId2 + "_t'></table>"),
localRowData2 = $(this).jqGrid("getLocalRow", rowId2);
$subgrid2.appendTo("#" + $.jgrid.jqID(subgridDivId2));
$subgrid2.jqGrid({
datatype: "local",
data: localRowData2.subgrid,
colNames: ["Col 1", "Col 2", "Col 3"],
colModel: [
{ name: "d1", width: 90 },
{ name: "d2", width: 90 },
{ name: "d3", width: 90 }
],
gridview: true,
rownumbers: true,
autoencode: true,
sortname: "d1",
sortorder: "desc",
height: "100%",
subGrid: isHasSubrids(localRowData2.subgrid),
loadComplete: removeSubgridIcon
});
}
});
}
});
The second demo is more deep modifications of the previous demo. It can be used in case of creating really deep multilevel subgrids. I used in the demo additionally intensive idPrefix
to simplify working with ids. I recommend to compare values of id
properties of items of myData
array in the first demo and in the second one. The code of the second demo is below
var myData = [
// main grid data
{ id: "1", col1: "11", col2: "12",
subgrid: [
// data for subgrid for the id=m1
{ id: "1", c1: "aa", c2: "ab", c3: "ac",
subgrid: [
// data for subgrid for the id=m1, subgridId=s1a
{ id: "1", d1: "2aa", d2: "2ab", d3: "2ac" },
{ id: "2", d1: "2ba", d2: "2bb", d3: "2bc" },
{ id: "3", d1: "2ca", d2: "2cb", d3: "2cc" }
]},
{ id: "2", c1: "ba", c2: "bb", c3: "bc" },
{ id: "3", c1: "ca", c2: "cb", c3: "cc" }
]},
{ id: "2", col1: "21", col2: "22",
subgrid: [
// data for subgrid for the id=m2
{ id: "1", c1: "1xx", c2: "1xy", c3: "1xz",
subgrid: [
// data for subgrid for the id=m2, subgridId=s2a
{ id: "1", d1: "2xx", d2: "2xy", d3: "2xz" }
]}
]},
{ id: "3", col1: "31", col2: "32" }
],
removeSubgridIcon = function () {
var $this = $(this),
idPrefix = $this.jqGrid("getGridParam", "idPrefix");
$this.find(">tbody>tr.jqgrow>td.ui-sgcollapsed").filter(function () {
var rowData = $this.jqGrid("getLocalRow",
$.jgrid.stripPref(idPrefix, $(this).closest("tr.jqgrow").attr("id")));
return rowData.subgrid == null;
}).unbind("click").html("");
},
isHasSubrids = function (data) {
var l = data.length, i;
for (i = 0; i < l; i++) {
if (data[i].subgrid != null) {
return true;
}
}
return false;
},
specificGridOptions = [
{
colNames: ["Column 1", "Column 2"],
colModel: [
{ name: "col1" },
{ name: "col2" }
],
cmTemplate: { width: 200 },
sortname: "col1",
sortorder: "desc",
idPrefix: "s_",
pager: "#pager",
caption: "Demonstrate how to create subgrid from local hierarchical data"
},
{
colNames: ["Colunm1", "Colunm2", "Colunm3"],
colModel: [
{ name: "c1" },
{ name: "c2" },
{ name: "c3" }
],
cmTemplate: { width: 112 },
sortname: "c1",
sortorder: "desc"
},
{
colNames: ["Col 1", "Col 2", "Col 3"],
colModel: [
{ name: "d1" },
{ name: "d2" },
{ name: "d3" }
],
cmTemplate: { width: 90 },
sortname: "d1",
sortorder: "desc"
}
],
commonGridOptions = {
datatype: "local",
gridview: true,
rownumbers: true,
autoencode: true,
height: "100%",
loadComplete: function () {
// one can use loadComplete: removeSubgridIcon, but I included
// curent implementation of loadComplete only to show how to call
// removeSubgridIcon from your loadComplete callback handler
removeSubgridIcon.call(this);
},
subGridRowExpanded: function (subgridDivId, rowId) {
var $subgrid = $("<table id='" + subgridDivId + "_t'></table>"),
subgridLevel = $(this).jqGrid("getGridParam", "subgridLevel") + 1,
parentIdPrefix = $(this).jqGrid("getGridParam", "idPrefix"),
pureRowId = $.jgrid.stripPref(parentIdPrefix, rowId),
localRowData = $(this).jqGrid("getLocalRow", pureRowId);
$subgrid.appendTo("#" + $.jgrid.jqID(subgridDivId));
$subgrid.jqGrid($.extend(true, {}, commonGridOptions, specificGridOptions[subgridLevel], {
data: localRowData.subgrid,
subGrid: isHasSubrids(localRowData.subgrid),
subgridLevel: subgridLevel,
idPrefix: rowId + "_",
rowNum: 10000 // we use this to have no pager in the subgrids
}));
}
};
$("#list").jqGrid($.extend(true, {}, commonGridOptions, specificGridOptions[0], {
data: myData,
subgridLevel: 0,
subGrid: isHasSubrids(myData)
}));