JQuery Grid-SubGrid for Parent-Child relation

I need some idea, about how to implement a subgrid in the following sceaniro.

The following is the json data that I want to display in the JQuery Grid and Subgrid. Basically I am getting an object called "Contact" that has a collection called "actionSet".

{
 "total" : "10",
 "page" : "1",
 "records" : "78",
 "rows" : [ {
   "comment" : null,
   "givenName" : "Contact A",
   "familyName" : "A",
   "actionSet" : [ {
       "actionID" : 1,
       "actionDueDate" : "2012-12-08",
       "actionNote" : "Action 1"
       }, {
       "actionID" : 2,
       "actionDueDate" : "2012-12-08",
       "actionNote" : "Action 2"
  } ]
 }    ...]

}

I want eache Grid row to display the "Contact" and the subgris associated with the grid should display "actionSet" collection.

When a particular row in the Grid is selected, I do not want to make a server call to get the associated actions, as they are allready present in the "actionSet".

I have got the Grid working, displaying the "Contacts" nicely, but I get confused while implement the subgrid, as how to get the data for it, as its allready available in json.

jq(function() {
 jq("#grid").jqGrid({
 url:'/smallworks/project/getall.do',
 datatype: 'json',
 mtype: 'GET',
   colNames:['Id', 'First Name', 'Last Name'],
   colModel:[
     {name:'id',index:'id', width:55,editable:false,editoptions:   {readonly:true,size:10},hidden:true},
   {name:'givenName',index:'givenName', width:100,editable:true, editrules:{required:true}, editoptions:{size:10}},
   {name:'familyName',index:'familyName', width:100,editable:true, editrules:{required:true}, editoptions:{size:10}}
  ],
  postData: {
  },
  rowNum:20,
  rowList:[20,40,60],
  height: 200,
  autowidth: true,
  rownumbers: true,
  pager: '#pager',
  sortname: 'id',
  viewrecords: true,
  sortorder: "asc",
  caption:"Contacts",
  emptyrecords: "Empty records",
  loadonce: false,
  loadComplete: function() {
  },

Is this achievable? Do I need to parse JSON data specially for the subgrid? How can this be achieved?


Solution 1:

I suggest that you save information from actionSet in an object which you can easy access later. For example you can use userData parameter and fill the userdata part of JSON data inside of beforeProcessing. The create subgrid you can follow the answer or another one.

The demo demonstrate the implementation approach:

enter image description here

It uses the following code

var mainGridPrefix = "s_";

$("#grid").jqGrid({
    url: "Adofo.json",
    datatype: "json",
    colNames: ["First Name", "Last Name"],
    colModel: [
        { name: "givenName" },
        { name: "familyName" }
    ],
    cmTemplate: {width: 100, editable: true, editrules: {required: true},
        editoptions: {size: 10}},
    rowNum: 20,
    rowList: [20, 40, 60],
    pager: "#pager",
    gridview: true,
    caption: "Contacts",
    rownumbers: true,
    autoencode: true,
    height: "100%",
    idPrefix: mainGridPrefix,
    subGrid: true,
    jsonReader: { repeatitems: false },
    beforeProcessing: function (data) {
        var rows = data.rows, l = rows.length, i, item, subgrids = {};
        for (i = 0; i < l; i++) {
            item = rows[i];
            if (item.actionSet) {
                subgrids[item.id] = item.actionSet;
            }
        }
        data.userdata = subgrids;
    },
    subGridRowExpanded: function (subgridDivId, rowId) {
        var $subgrid = $("<table id='" + subgridDivId + "_t'></table>"),
            pureRowId = $.jgrid.stripPref(mainGridPrefix, rowId),
            subgrids = $(this).jqGrid("getGridParam", "userData");

        $subgrid.appendTo("#" + $.jgrid.jqID(subgridDivId));
        $subgrid.jqGrid({
            datatype: "local",
            data: subgrids[pureRowId],
            colNames: ["Due Date", "Note"],
            colModel: [
                { name: "actionDueDate", formatter: "date", sorttype: "date" },
                { name: "actionNote" }
            ],
            sortname: "actionDueDate",
            height: "100%",
            rowNum: 10000,
            autoencode: true,
            autowidth: true,
            jsonReader: { repeatitems: false, id: "actionID" },
            gridview: true,
            idPrefix: rowId + "_"
        });
    }
});

UPDATED: The JSON data used in the demo one can see below. I added id property which is required for jqGrid. I used actionID as the id of the subgrids:

{
    "total": "10",
    "page": "1",
    "records": "78",
    "rows": [
        {
            "id": 10,
            "comment": null,
            "givenName": "Contact A",
            "familyName": "A",
            "actionSet": [
                {
                    "actionID": 1,
                    "actionDueDate": "2012-12-08",
                    "actionNote": "Action 1"
                },
                {
                    "actionID": 2,
                    "actionDueDate": "2012-12-09",
                    "actionNote": "Action 2"
                }
            ]
        },
        {
            "id": 20,
            "comment": null,
            "givenName": "Contact B",
            "familyName": "B",
            "actionSet": [
                {
                    "actionID": 3,
                    "actionDueDate": "2012-12-11",
                    "actionNote": "Action 3"
                },
                {
                    "actionID": 4,
                    "actionDueDate": "2012-12-10",
                    "actionNote": "Action 4"
                }
            ]
        }
    ]
}