I have an XML file having a structure like this:
<products>
<product>
<id>P1</id>
<name>PRODUCT 1</name>
<accessories>
<accessory>
<id>acc_1</id>
<name></name>
</accessory>
<accessory>
<id>acc_2</id>
<name></name>
</accessory>
<accessory>
<id>acc_3</id>
<name></name>
</accessory>
</accessories>
</product>
<product>
<id>P2</id>
<name>PRODUCT 2</name>
<accessories>
<accessory>
<id>acc_1</id>
<name>ACC 1</name>
</accessory>
<accessory>
<id>acc_2</id>
<name>ACC 2</name>
</accessory>
</accessories>
</product>
</products>
I want to have all products in a Grid using jqGrid and the accessories in a subgrid for each product (with the plus icon).
For that I use the following js:
var myGrid = $("#prods").jqGrid({
url: 'products.xml',
datatype: "xml",
colNames:["id", "Name"],
colModel:[
{name:"id", key: true, index:"id", width:90, xmlmap:"id", sortable:true},
{name:"Name", index:"Name", width:100, sortable:true, xmlmap:"name"}}
],
width: 300,
height:480,
ignoreCase: true,
viewrecords: true,
loadonce: true,
sortname: 'Name',
sortorder: "asc",
sortable: true,
pager: "#pager",
xmlReader: {
root: "products",
row: "product",
repeatitems: false,
id: "sku",
subgrid: {
root: "products>product>accessories",
row: "accessory",
repeatitems:false,
id: "id"
}
},
caption: "Products",
subGrid: true,
subGridRowExpanded: function(grid_id, row_id) {
var subgrid_table_id;
subgrid_table_id = grid_id + "_t";
jQuery("#" + grid_id).html("<table id='" + subgrid_table_id + "' class='scroll'></table>");
jQuery("#" + subgrid_table_id).jqGrid( {
colNames: [ 'Id', 'Name'],
colModel: [
{name:"accid",index:"accid",width:80, xmlmap:"id"},
{name:"accname",index:"accname",width:80, xmlmap:"name"}
],
height: 50,
rowNum:10,
});
}
});
It does not shows the subrecords. I tried also to put the same root / row in the subgrid as the parent grid and using the reference like this for the ID: "products>product>accessories>accessory>id" but it does not work as well.
Anybody have already found an example which works (in fact my data source is the same file for both grid/subgrid) like I want.
Hope this is clear enough, otherwise do not hesitate to comment for requesting more details.
Subgrids feature of jqGrid is mostly provided for dynamically filled data. I mean, that on every click on the plus sign it will be made an
jQuery.ajax
call to get the data from the server. You want get get the whole grid and subgrid data in one XML response (in one XML file). For the case I can suggest you two alternative implementation ways.The first one you can see live here. The second one here.
The first change which required in your grid is the usage of
xmlmap:">id"
andxmlmap:">name"
instead ofxmlmap:"id"
andxmlmap:"name"
. It is required because the XML data for the subgrid has the same XML element names like the main grid.Now some comments to the code. The first version of the solution use
subGridUrl
with the same url like for the main grid. So to be able to read the correct part of the XML data I modifyxmlReader.subgrid.root
parameter of jqGrid on every subgrid expand (inside of subGridBeforeExpand).One can make the loading of products.xml file from the server even more quickly is one use local caching of the previous requests. To do this one either
prmNames: {nd:null,page:null,rows:null,sort:null,order:null,search:null}
parameter of jqGrid orserializeGridData: function() { return ""; }
orpostData:""
which all remove all parameters sending to the server. To remove additional parameters from the GET request of the subgrid data I useserializeSubGridData: function() {return "";}
.The full code of the first solution is here:
Another solution not use the
subgrid
part ofxmlReader
and just use the subGridRowExpanded in the Subgrid as grid style, but I usedatatype:'xmlstring'
instead ofdatatype:'xml'
. In the code below I use small trick thatdatatype:'xmlstring'
accept not only strings as the value of thedatastr
parameter. Instead of that one can use pure XML parsed data. So I save the parsed XML data inside ofloadComplete
in an variable and then just use the previous saved parsed XML data.The full code of the second solution is here: