Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
439 views
in Technique[技术] by (71.8m points)

jquery - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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)
}));

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...