jqGrid: проблема с загрузкой вложенной подсетки с локальным типом данных

Я пытаюсь заставить вложенные подсетки работать с использованием jqGrid с локальными данными. Я искал вокруг совсем немного, но не смог найти решение. Вот упрощенный пример моего кода:

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

            }                
        });
    }
});

Есть идеи?


person Jon L    schedule 07.12.2012    source источник


Ответы (1)


Я нахожу ваш вопрос интересным. Я думаю, что ответ может быть полезен для многих других людей. Поэтому я написал две демонстрации, в которых демонстрирую, как можно реализовать требования.

введите здесь описание изображения

Первая демонстрация основана на демонстрации из мой предыдущий ответ (который основан на другом), какой код вы уже использовали в тексте вашего вопроса. Я добавил трюк из ответа, чтобы дополнительно скрыть значок подсетки ("+") для строк, не имеющих подсеток.

Чтобы упростить хранение данных подсетки, я добавил в каждую строку свойство subgrid, значением которого являются данные для подсетки. Такой вид хранения данных очень практичен, потому что jqGrid сохраняет полные элементы строки, поэтому вам больше не нужны скрытые столбцы. Для доступа к локальным данным рекомендую использовать метод getLocalRow. См., например, ответ для получения дополнительной информации или исходный код очень простого метода getLocalRow.

Код первой демонстрации:

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

Вторая демонстрация представляет собой более глубокую модификацию предыдущей демонстрации. Его можно использовать в случае создания действительно глубоких многоуровневых подсеток. Я использовал в демо дополнительно интенсивный idPrefix для упрощения работы с id. Рекомендую сравнить значения id свойств элементов массива myData в первой демо и во второй. Код второго демо ниже

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)
}));
person Oleg    schedule 08.12.2012
comment
Спасибо Олег, отличное решение! Я уже начал терять надежду, пока не увидел это. Это как раз то, что я ищу. Продолжайте хорошую работу. (Я пытался проголосовать за ответ, но у меня недостаточно очков репутации..) - person Jon L; 12.12.2012
comment
@JonL: Добро пожаловать! Это не проблема. Если вы примете мой ответ, вы получите 3 дополнительных очка репутации. После того, как вы наберете 15 очков репутации, вы получите право голосовать за 30 вопросов или ответов в день. Ваш первый вопрос был очень интересным. Вероятно, вам, как и мне, понравится stakoverflow. С наилучшими пожеланиями! - person Oleg; 12.12.2012
comment
@neverwinter: это зависит от того, какой режим редактирования вы хотите использовать и где сохранить изменения. В случае локального редактирования в режиме редактирования ячеек вам нужно просто добавить опции cellEdit: true, cellsubmit: "clientArray" ко всем сеткам/подсеткам, которые необходимо редактировать. - person Oleg; 09.12.2014
comment
@Oleg Мои данные были в [{id:1,code:112,name:aa,group:1},{id:2,code:112,name:aa,group:2},{id:3,code: 113, имя: bb, группа: 1}, {id: 4, код: 113, имя: bb, группа: 2}], и я преобразовал это в этот формат данных [112] = {код: 112, имя: аа, subgrid[{grp1obj,grp2obj}]}, data[113] = {code:113,name:bb,subgrid[{grp1obj,grp2obj}]}, теперь я не могу назначить данные основной сетке. - person Haider; 25.01.2016
comment
@Haider: Извините, но я не понимаю, что вы делаете и что пытаетесь реализовать. Какую версию и какой форк jqGrid вы используете (или можете использовать)? Вы используете datatype: "local" или загружаете данные с сервера? Какой colModel вы используете? Вы должны открыть новый вопрос и описать все в деталях. - person Oleg; 25.01.2016
comment
@Oleg, я использую тип данных: локальный, мои данные в формате, используемом для создания простой сетки, я могу применить к ним группировку, используя код поля группы, но я хочу использовать данные для создания подсетки вместо групп - person Haider; 25.01.2016
comment
@Haider: Какая у тебя сейчас проблема? Повторяю предыдущий вопрос: какая версия jqGrid и от какого форка (бесплатный jqGrid , Guriddo jqGrid JS или старый jqGrid версии ‹=4.7), который вы используете (или можете использовать) ? Как вы определили colModel? Какие свойства и столбцы определены в subgrid, grp1obj, grp2obj? Я могу продолжить. Будет лучше, если вы подробно опишите свою проблему в новом вопросе. - person Oleg; 25.01.2016