Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jqGrid : issue loading nested sub grid with local datatype

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 sample of my code:

var mainGridData =
    [
        // main grid data
        { id: "m1", col1: "11", col2: "12" },
        { id: "m2", col1: "21", col2: "22" },
        { id: "m3", col1: "31", col2: "32" }
    ];
var firstSubgrid =
    {
        m1: [
            // data for subgrid for the id=m1
            { id: "s1a", c1: "aa", c2: "ab", c3: "ac" },
            { id: "s1b", c1: "ba", c2: "bb", c3: "bc" },
            { id: "s1c", c1: "ca", c2: "cb", c3: "cc" }
        ],
        m2: [
            // data for subgrid for the id=m2
            { id: "s2a", c1: "xx", c2: "xy", c3: "xz" }
        ]
    };
var secondSubgrid =
    {
        s1a: [
            // data for subgrid for the id=m1
            { id: "2s1a", d1: "2aa", d2: "2ab", d3: "2ac" },
            { id: "2s1b", d1: "2ba", d2: "2bb", d3: "2bc" },
            { id: "2s1c", d1: "2ca", d2: "2cb", d3: "2cc" }
        ],
        s2a: [
            // data for subgrid for the id=m2
            { id: "2s2a", d1: "xx", d2: "xy", d3: "xz" }
        ]
    };


//------------
$("#grid").jqGrid({
    datatype: 'local',
    data: mainGridData,
    colNames: ['Column 1', 'Column 2'],
    colModel: [
        { name: 'col1', width: 200 },
        { name: 'col2', width: 200 }
    ],
//Subgrid1...
    subGrid: true,
    subGridRowExpanded: function (subgridDivId, rowId) {
        var subgridTableId = subgridDivId + "_t";
        $("#" + subgridDivId).html("<table id='" + subgridTableId + "'></table>");
        $("#" + subgridTableId).jqGrid({
            datatype: 'local',
            data: firstSubgrid[rowId],
            colNames: ['Col 1', 'Col 2', 'Col 3'],
            colModel: [
                { name: 'c1', width: 100 },
                { name: 'c2', width: 100 },
                { name: 'c3', width: 100 }
            ],
      //Subgrid2...    
            subGrid: true,
            subGridRowExpanded: function (subgrid2DivId, subRowId2) {
                var subgrid2TableId = subgrid2DivId + "_t";
                $("#" + subgrid2DivId).html("<table id='" + subgrid2DivId + "'></table>");
                $("#" + subgrid2TableId).jqGrid({
                    datatype: 'local',
                    data: secondSubgrid[subRowId2],
                    colNames: ['Col 1', 'Col 2', 'Col 3'],
                    colModel: [
                        { name: 'd1', width: 100 },
                        { name: 'd2', width: 100 },
                        { name: 'd3', width: 100 }
                    ],
                });

            }                
        });
    }
});

Any ideas out there?

like image 991
Jon L Avatar asked Feb 18 '23 05:02

Jon L


1 Answers

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.

enter image description here

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)
}));
like image 100
Oleg Avatar answered Feb 21 '23 01:02

Oleg