【问题标题】:jqgrid - inline editing, post only changed datajqgrid - 内联编辑,仅发布更改的数据
【发布时间】:2016-02-03 20:10:43
【问题描述】:

我有一个 jqGrid,我想在其中检查单元格数据并仅发布数据已更改的列。

认为这是我的colModel

colModel: [{
    name: 'I_PK',
    index: 'u.I_PK',
    align: 'right',
    editable: false,
    sopt: ['cn', 'eq', 'ne', 'lt', 'le', 'gt', 'ge', 'bw', 'ew', 'nc']
}, {
    name: 'W3LabelSelected',
    index: 'u.W3LabelSelected',
    align: 'center',
    width: 170,
    editable: false,
    edittype: 'checkbox',
    formatter: "checkbox",
    search: false,
    formatoptions: {
        disabled: false
    },
    editoptions: {
        value: "1:0"
    }
}, {
    name: 'I_ItemNumID',
    index: 'u.I_ItemNumID',
    align: 'right',
    editable: true,
    editoptions: {
        dataEvents: [{
            type: 'focusin',
            fn: function (e) {
                var elem = e.target;
                setTimeout(function () {
                    elem.select();
                }, 50);
            }
        }]
    }
}, {
    name: 'Quantity',
    index: 'u.Quantity',
    align: 'right',
    editable: true,
    editoptions: {
        dataEvents: [{
            type: 'focusin',
            fn: function (e) {
                var elem = e.target;
                setTimeout(function () {
                    elem.select();
                }, 50);
            }
        }]
    }
}],

在这个网格中,我的两列是可编辑的。现在假设我在内联编辑中对任何行的其中一列进行了更改,那么应该只发布该单元格的值。当前功能发布该特定行的所有单元格。这可能吗?

我发现了一些关于此的问题 herethere,但似乎都没有解决这个特定问题。

基本上我能想到的想法是,在保存之前,如果我可以在发布之前以某种方式将该行的所有可编辑单元格的原始数据与新值进行比较,我可以消除数据没有的单元格已更改,仅发布已更改的单元格。

示例网格:http://jsfiddle.net/dipenshah8/HJema/203/

【问题讨论】:

    标签: javascript jquery jqgrid free-jqgrid


    【解决方案1】:

    我建议你使用内联编辑的serializeSaveData 回调或旧版本jqGrid 的serializeRowData 回调。回调允许您自定义将发送到服务器的数据。修改后的演示 http://jsfiddle.net/OlegKi/HJema/206/ 使用以下选项:

    inlineEditing: {
        keys: true,
        serializeSaveData: function (postData) {
            var changedData = {}, prop, p = $(this).jqGrid("getGridParam"),
                idname = p.keyName || p.prmNames.id;
    
            for (prop in postData) {
                if (postData.hasOwnProperty(prop) &&
                    (postData[prop] !== p.savedRow[0][prop] || prop === idname)) {
                    changedData[prop] = postData[prop];
                }
            }
            alert(JSON.stringify(changedData));
            return changedData;
        }
    }
    

    serializeSaveData回调的代码会枚举所有默认发送到服务器的属性,并生成新的对象changedData而不是postData。该代码将postData的所有属性值与savedRow[0]参数的对应值进行比较,该参数包含开始编辑之前的行。

    更新:如果数据可以有formatter: "date",上面的代码应该稍微复杂一些。 jqGrid 将 formatted 值保存在 savedRow[0] 中。可以将上面的代码修改为:

    inlineEditing: {
        keys: true,
        serializeSaveData: function (postData) {
            var changedData = {}, prop, p = $(this).jqGrid("getGridParam"),
                idname = p.keyName || p.prmNames.id,
                oldValue, cm, formatoptions;
    
            for (prop in postData) {
                oldValue = p.savedRow[0][prop];
                if (p.iColByName[prop] != null) {
                    cm = p.colModel[p.iColByName[prop]];
                    formatoptions = cm.formatoptions || {};
                    if (cm.formatter === "date" && formatoptions.sendFormatted !== true) {
                        oldValue = $.unformat.date.call(this, oldValue, cm);
                    }
                }
                if (postData.hasOwnProperty(prop) &&
                        (postData[prop] !== oldValue || prop === idname)) {
                    changedData[prop] = postData[prop];
                }
            }
            alert(JSON.stringify(changedData));
            return changedData;
        }
    }
    

    查看修改后的演示http://jsfiddle.net/OlegKi/HJema/209/

    【讨论】:

    • 嗨@Oleg 谢谢你这很好用。我对此的一个问题是,在我的其他网格之一中,我使用日期选择器来编辑该列的日期时间值。当我尝试编辑该字段而不进行更改并且尝试保存它时,它仍然会被发布。这只发生在日期时间字段的情况下。我放了一个演示 here 来澄清我的问题。有空的时候可以看看吗?
    • @DipenShah:不客气!我修复了代码。请参阅答案的更新部分和修改后的演示。
    • @Oleg 如果行内编辑时数据没有改变,如果行被保存,如何禁用服务器回调并简单地取消行内编辑模式?
    • @DipenShah:在我看来,由于使用了formatoptions: { disabled: false } 并希望使用不可编辑 ( editable: falseeditable: "hidden")。我在the answer 中用formatoptions: { disabled: false} 描述了一个实现,但它使用datatype: "local"。为什么不直接删除formatoptions: { disabled: false},设置editable: true?您可能想要的是在用户单击复选框的情况下反转复选框。不是吗?...
    • @DipenShah: ... 你在onSelectRow 内部开始editRow,你有e 作为这里的最后一个参数。您可以测试e.target,无论是$(e.target).is("i.fa-square-o") 还是$(e.target).is("i.fa-check-square-o"),然后用户单击复选框。您可以测试$(e.target).closest("tr.jqgrow>td")[0].cellIndex === p.iColByName.W3LabelSelected 以确保用户单击了“复选框”。您可以在特殊情况下使用editRowoneditfunc 回调来反转(模拟click)复选框($("#" + rowid + "_W3LabelSelected").click())。我认为它应该可以工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多