【问题标题】:jqgrid v5.2.1 with subgrid and local data CRUD operationsjqgrid v5.2.1 带有子网格和本地数据 CRUD 操作
【发布时间】:2018-05-13 07:53:18
【问题描述】:

这是我的场景。当页面加载时,我的 jqgrid v5.2.1 不显示任何数据。这是设计使然。用户要么必须手动输入网格和子网格的所有数据,要么单击按钮以通过
以 json 格式从服务器加载默认数据 $("#jqGrid").jqGrid('setGridParam', { datatype: 'local', data: dataResponse.groups }).trigger("reloadGrid");

用户在本地执行 CRUD 操作,直到数据正确,在这种情况下单击按钮,网格数据通过 $("#jqGrid").jqGrid('getGridParam', 'data') 进入服务器。

编辑/删除操作在加载默认数据时工作正常,但我在添加新记录时遇到问题。

新行的 ID 总是 _empty(这很好,因为服务器端会生成它),但是来自子网格的新行不会传输到服务器。问题是如何建立主网格中新创建的行与子网格中的关联行之间的关系,然后将所有内容传输到服务器进行处理?

代码如下:

var mainGridPrefix = "s_";

        $("#jqGrid").jqGrid({
            styleUI: 'Bootstrap',
            datatype: 'local',        
            editurl: 'clientArray',               
            postData: {},
            colNames: ['Id', 'Group', 'Group Description', 'Markets', 'Group sort order'],
            colModel: [
                { name: 'id', key: true, hidden: true },
                { name: 'name', width: 300, sortable: false, editable: true, editrules: { required: true }, editoptions: { maxlength: 50 } },
                { name: 'description', width: 700, sortable: false, editable: true, editoptions: { maxlength: 256 } },
                { name: 'market', width: 200, sortable: false, editable: true, editrules: { required: true }, editoptions: { maxlength: 50 }  },
                { name: 'sortOrder', width: 130, sortable: false, editable: true, formatter: 'number', formatoptions: { decimalSeparator: ".", thousandsSeparator: ',', decimalPlaces: 2 } }
            ],
            sortname: 'Id',
            sortorder: 'asc',
            idPrefix: mainGridPrefix,
            subGrid: true,
            //localReader: { repeatitems: true },
            jsonReader: { repeatitems: false},
            autowidth: true,               
            shrinkToFit: true,                
            loadonce: true,
            viewrecords: true,
            rowNum: 5000,
            pgbuttons: false,
            pginput: false,                
            pager: "#jqGridPager",
            caption: "Group Template",
            altRows: true,
            altclass: 'myAltRowClass',               
            beforeProcessing: function (data) {
                var rows = data.rows, l = rows.length, i, item, subgrids = {};
                for (i = 0; i < l; i++) {
                    item = rows[i];
                    if (item.groupItems) {
                        subgrids[item.id] = item.groupItems;
                    }
                }                   
                data.userdata  = subgrids;
            },               
            subGridRowExpanded: function (subgridDivId, rowId) {
                var $subgrid = $("<table id='" + subgridDivId + "_t'></table>"),
                    pureRowId = $.jgrid.stripPref(mainGridPrefix, rowId),
                    subgrids = $(this).jqGrid("getGridParam", "userData"),
                    subgridPagerId = subgridDivId + "_p";

                $("#" + $.jgrid.jqID(subgridDivId)).append($subgrid).append('<div id=' + subgridPagerId + '></div>');

                $subgrid.jqGrid({
                    datatype: "local",
                    styleUI: 'Bootstrap',
                    data: subgrids[pureRowId],
                    editurl: 'clientArray',
                    colNames: ['Item', 'Item Description', 'Health Standard', 'Sort order', 'Statuses', 'Risks', 'Solutions', 'Budgets'],
                    colModel: [
                        { name: 'itemName', width: '200', sortable: false, editable: true, editrules: { required: true }, editoptions: { maxlength: 50 }  },
                        { name: 'itemDescription', width: '400', sortable: false, editable: true, editoptions: { maxlength: 500 }  },
                        { name: 'healthStandard', width: '400', sortable: false, editable: true, editoptions: { maxlength: 500 }  },
                        { name: 'itemSortOrder', width: '200', sortable: false, editable: true, formatter: 'number', formatoptions: { decimalSeparator: ".", thousandsSeparator: ',', decimalPlaces: 2 } },
                        { name: 'statuses', width: '400', sortable: false, editable: true, editoptions: { maxlength: 500 }  },
                        { name: 'risks', width: '400', sortable: false, editable: true, editoptions: { maxlength: 500 } },
                        { name: 'solutions', width: '400', sortable: false, editable: true, editoptions: { maxlength: 500 } },
                        { name: 'budgets', width: '400', sortable: false, editable: true, editoptions: { maxlength: 100 } }
                    ],
                    //rownumbers: true,
                    rowNum: 5000,
                    autoencode: true,
                    autowidth: true,
                    pgbuttons: false,
                    viewrecords: true,
                    pginput: false,
                    jsonReader: { repeatitems: false, id: "groupId" },
                    gridview: true,
                    altRows: true,
                    altclass: 'myAltRowClass',
                    idPrefix: rowId + "_",
                    pager: "#" + subgridPagerId
                });

                $subgrid.jqGrid('navGrid', "#" + subgridPagerId, { edit: true, add: false, del: true, search: true, refresh: false, view: false  }, // options
                    { closeAfterEdit: true }, // edit options  //recreateForm: true
                    { closeAfterAdd: true },  // add options
                    {},   //del options
                    {}  // search options
                );
            }               
        });

        $('#jqGrid').navGrid('#jqGridPager', { edit: true, add: false, del: true, search: true, refresh: false, view: false }, // options
            // options for Edit Dialog
            {                   
                editCaption: "Edit Group",                   
                beforeShowForm: function (form) {
                    form.closest('.ui-jqdialog').center();
                },                    
                bottominfo: "<br/>",
                recreateForm: true,
                closeOnEscape: true,
                closeAfterEdit: true                    
            },
            // options for Add Dialog
            {

                //url:'clientArray',
                addCaption: "Add Group",                   
                beforeShowForm: function (form) {
                    form.closest('.ui-jqdialog').center();
                },                   
                bottominfo: "<br/>",
                recreateForm: true,
                closeOnEscape: true,
                closeAfterAdd: true                    
            },  
            // options for Delete Dailog
            {
                caption: "Delete Group",
                beforeShowForm: function (form) {
                    form.closest('.ui-jqdialog').center();
                },
                msg: "Are you sure you want to delete?",
                recreateForm: true,
                closeOnEscape: true,
                closeAfterDelete: true                    
            },
            // options for Search Dailog
            {
                caption: "Search Group",
                beforeShowForm: function (form) {
                    form.closest('.ui-jqdialog').center();
                },                   
                recreateForm: true,
                closeOnEscape: true,
                closeAfterDelete: true
            }
        );     

【问题讨论】:

  • 主网格的关键行是id,但是子网格的哪个字段连接到主id字段?
  • 在代码中添加行被禁用 - 用户如何在网格和子网格中添加记录?或者这是一个应该同步工作的任务
  • 在此处发布之前,我忘记启用添加功能。假设 add 设置为 true 如何链接主网格和子网格,以便用户可以添加行并发布到服务器?

标签: jqgrid local crud


【解决方案1】:

表单编辑中存在一个小错误,现已修复。感谢您帮助我们找到它们。

现在问题来了。

当您在主网格中添加数据时,很自然地会为每一行添加一个唯一的 id。由于该错误而不是使用 Guriddo id 生成器插入一行,因此使用 id = s_empty 插入错误。这会导致主网格中每个插入的行都具有相同的 id,这是不正确的。

该修复已在 GitHub 上发布,您可以尝试一下。

我们更新了您的演示,以便在子网格中插入正确的数据。唯一的小补充是在添加模式下的 afterSubmit 事件中,其中创建了所需的项目。

希望这能解决问题

这里是demo with the fixed version

已编辑

在服务器上,如果包含字符串'jqg',您可以分析 id 列,这将指出这是一个新行。子网格对应的 id 在 userData 模块中,它将主网格 id 与子网格数据连接起来

编辑 2

您想要实现的一种可能的解决方案是获取主数据并使用 userData 属性获取子网格数据。在此之后对主数据进行循环并像这样更新它

var maindata =  $("#jqGrid").jqGrid('getGridParam', 'data');
var subgrids = $("#jqGrid").jqGrid('getGridParam', 'userData');

for(var i= 0;i < maindata.length;i++) {
    var key = maindata[i].id;
    if(subgrids.hasOwnProperty(key) ) {
        if(!maindata[i].hasOwnProperty(groupItems) ) {
            maindata[i].groupItems = [];
        }
        maindata[i].groupItems = subgrids[key];
    }
}

代码没有经过测试,但我想你明白了。

另一种方法是更新 subgrid 的每个 CRUD 上的 groupitems,我认为这并不难实现。

【讨论】:

  • 感谢托尼的回复。您的修复解决了 _empty id 问题,但没有解决我的问题。
  • 感谢托尼的回复。您的修复解决了 _empty id 问题,但没有解决我的问题。请在您的演示中执行以下操作,您就会明白我的意思。启动您的演示页面,一旦您的数据(主数据)被加载,从两个网格中删除所有行。您的网格和子网格将完全为空。然后向主网格添加一行,向子网格添加一行。现在尝试通过 var testdata = $("#jqGrid").jqGrid('getGridParam', 'data') 读取网格数据,您会看到子网格数据不存在。我在主网格中缺少 groupItems 绑定。感谢您的帮助。
  • 我的目标是从完全空的网格开始,一旦用户向网格添加行,读取两个网格中的数据并将其发送到服务器。
  • 您发布的代码是错误的,它永远不会包含主网格数据中的新分组项。只需尝试使用您的代码编辑/添加/删除子网格中的一些现有行,您的主网格数据不会更改。您有两个选择 - 要么在发布时重建主网格的数据,要么在网格和子网格的任何操作中更新它。
  • 谢谢托尼。只需稍微更改您的代码,现在一切都按预期工作。
猜你喜欢
  • 2012-04-27
  • 2015-04-17
  • 1970-01-01
  • 2020-08-29
  • 2015-08-07
  • 2011-03-12
  • 1970-01-01
  • 2012-11-25
  • 1970-01-01
相关资源
最近更新 更多