如何在免费 jqgrid 中编辑表单后设置行 ID 值

How to set row id value after form editing in free jqgrid

Table 具有包含 3 列(Grupp、Kuu、Toode)的主键和从这些列创建的服务器 returns ID。

在表单编辑中更改主键列后,服务器返回新的行 ID。

免费的 jqgrid 不会将此行 ID 设置为已更改的行 ID。服务器 returns 新 ID。

我试图通过使用

在 editfor afterSubmit 方法中更改下面代码中的 id
function EditAddForm_AfterSubmit(response, postdata) {
  var json = $.parseJSON(response.responseText);
  return [true, '', json.Id];
  }

但如果再次编辑行,旧 ID 仍会传递给服务器。

重现步骤:

  1. 在Chrome
  2. 中打开下面的页面 单击
  3. Select 行
  4. 使用工具栏编辑按钮打开表单编辑器
  5. 更改字段 Kuu 值
  6. 按提交按钮。在 jqgrid
  7. 的 Kuu 列中更改了值
  8. 双击行开始行编辑
  9. 按回车键。由于错误的(旧的)主键,来自服务器应用程序的错误消息 传递给服务器。

代码:

  <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <base href="http://example.com/" />
        <link rel="stylesheet" href="http://example.com/themes/redmond/jquery-ui.css" type="text/css" />
        <link rel="stylesheet"
              href="//netdna.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
        <link href="http://example.com/Content/Css/normalize.css" rel="stylesheet"/>
    <link href="http://example.com/Scripts/jqgrid-4.8.0/css/ui.jqgrid.css" rel="stylesheet"/>


    <title>
Old primary key value is passed if primary key is changed
    </title>
    <script type="text/javascript">
        "use strict";
        var BASE_URL = 'http://example.com/',
            Message = {
                selectRows: "Select",
                sendingQuery: "Send"
                };
    </script>

<script src="http://example.com/Scripts/jquery-1.11.2.js"></script>
<script src="http://example.com/Scripts/jquery-ui-1.11.4.js"></script>
<script src="http://example.com/Scripts/jqgrid-4.8.0/js/jquery.jqgrid.src.js"></script>
<script src="http://example.com/Scripts/json2.js"></script>
<script src="http://example.com/Scripts/erp.js"></script>
<script src="http://example.com/Scripts/AfterGridInit.js"></script>
<script src="http://example.com/Scripts/TinyMCE/tiny_mce.js"></script>
<script src="http://example.com/Scripts/TinyMCE/jquery.tinymce.js"></script>

    <script type="text/javascript">
    var 
        $grid,
        lastSelectedRow,
        autoedit = false,

          jqXHRFromOnSuccess,
          idsOfSelectedRows,
          myColumnsState,
          isColState,
          myColumnStateName;

    $.extend(true, $.jgrid.defaults, {
        mtype: 'POST',

        iconSet: "fontAwesome" ,
        navOptions: {
            position: "center"},

        autoResizing: { compact: true,widthOfVisiblePartOfSortIcon: 13 },
        toppager: true,
        viewrecords: false,
        onSelectRow: grid_onSelectRow,
        onSelectAll: grid_onSelectAll,

        sortable: function (permutation) {
            saveWindowState();
        },
        multiselect: true,
        ajaxRowOptions: { async: true },
        scrollrows: true,
        prmNames: {  
            id: "_rowid", page: "_page", rows: "_rows", oper: "_oper", sort: "_sidx", order: "_sord",
            nd: "_nd"
        },
        loadui: 'block',



          cmTemplate: { fixed: true, autoResizable: true },
        autoencode: true,
        gridview: true,

        serializeGridData: function (postData) {

            var myPostData = $.extend({}, postData);
            myPostData._filters = myPostData.filters;
            delete myPostData._oper;
            delete myPostData.filters;
            delete myPostData.searchField;
            delete myPostData.searchString;
            delete myPostData.searchOper;
            return myPostData;
        },

        shrinkToFit: false

    });

    $.extend(true,$.jgrid.edit, {
        beforeSubmit: function (postdata, formid) {
            showModeless('Saving');
            return [true, ""];
        },

        closeAfterAdd: true,
        recreateForm: true,
        reloadAfterSubmit: false
    });
</script>
</head>

<body>
    <div id="container">

<script type="text/javascript">
    var editParams =  {
      // code added according to proposed answer
      afterComplete: function (jqXhr, postdata, $form, formOper) {
            if (formOper !== "add") {
                var json = $.parseJSON(jqXhr.responseText);
                $("#" + $.jgrid.jqID(postdata._rowid)).attr(json.Id);
            }
        },

        afterSubmit: function (response, postdata) {
            return EditAddForm_AfterSubmit(response, postdata);
        },

      url: 'http://example.com/Grid/Edit?_entity=Grnait',
      closeAfterEdit: true
      };

    function selectedRowsAction(action) {
    }

    $(function () {
        'use strict';
        $('body').css('overflow-y', 'hidden');
        var urlFilters,
                namedParameters = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'),
                parameters = {},
                nameAndValue,
                i,
                cm= [{"hidden":false,"label":"Tegevus","name":"_actions","search":false,"width":72
,"sortable":false,"formatter":"actions","viewable":false,"formatoptions":{"editbutton":true,"onSuccess":function (jqXHR) { jqXHRFromOnSuccess=jqXHR;return true;}
,"delbutton":true,"delOptions":{"url":"http://localhost:52216/admin/Grid/Delete?_entity=Grnait","afterComplete":function (response, postdata, formid) { 
summarefresh($grid);
$grid[0].focus(); 
}
}}},{"label":"Objekt","name":"Grupp","index":"Grupp","edittype":"select","editoptions":{"formatter":"select","value":":;1:1;11:11;14:14;2:2;21:21;22:22;23:23;251:251;30:30;31:31;40:40;41:41","class":"ui-widget-content jqgrid-inlineedit-element","style":"width:100%;max-width:210px;height:130%","dataEvents":[{"type":"change","fn":function(e) {
updateSelectValue(this, 'Grupp');
dataChanged(this);
}
},{"type":"keydown","fn":function(e) {
if(!enter(e)) return;
updateSelectValue(this, 'Grupp');
dataChanged(this);
}
},{"type":"focus","fn":function(e) {if(typeof e.target.ischanged=='undefined') {e.target.ischanged=false}}
}]},"searchoptions":{"sopt":["cn","eq","ne","lt","le","gt","ge","bw","ew","nc"]},"editable":true,"width":70,"hidden":false},{"label":"Artikkel","name":"Toode","index":"Toode","edittype":"custom","editoptions":{"maxlength":20,"size":20,"lookup":"ToodeL","custom_element":function(value, options) {
return combobox_element(value, options,'38','Toode','Grnait','YToode')}
,"custom_value":combobox_value
},"searchoptions":{"sopt":["cn","eq","ne","lt","le","gt","ge","bw","ew","nc"]},"editable":true,"width":60,"hidden":false},{"label":"Artikli nimi","name":"Toode0_nimetus","index":"Toode0_nimetus","edittype":"custom","editoptions":{"maxlength":0,"size":0,"lookup":"ToodeL","custom_element":function(value, options) {
return combobox_element(value, options,'78','Toode0_nimetus','Grnait','ArtikliNimi%c3%9c%c3%bcriarvestusel')}
,"custom_value":combobox_value
},"searchoptions":{"sopt":["cn","eq","ne","lt","le","gt","ge","bw","ew","nc"]},"editable":true,"width":100,"hidden":false},{"label":"Algnäit","name":"Anait","index":"Anait","align":"right","searchoptions":{"sopt":["eq","ne","lt","le","gt","ge"]},"editoptions":{"maxlength":13,"dataEvents":[{"type":"change","fn":function(e) {dataChanged(e.target)}
},{"type":"focus","fn":function(e) {if(typeof e.target.ischanged=='undefined') {e.target.ischanged=false}}
}],"style":"text-align:right","readonly":null,"class":"jqgrid-inlineedit-element ","disabled":null},"editable":true,"width":63,"classes":null,"hidden":false},{"label":"Kuu","name":"Kuu","index":"Kuu","editoptions":{"maxlength":6,"size":6,"dataEvents":[{"type":"change","fn":function(e) {dataChanged(e.target)}
},{"type":"focus","fn":function(e) {if(typeof e.target.ischanged=='undefined') {e.target.ischanged=false}}
}],"readonly":null,"class":"jqgrid-inlineedit-element ","disabled":null},"editable":true,"width":43,"classes":null,"hidden":false,"searchoptions":{"sopt":["cn","eq","ne","lt","le","gt","ge","bw","ew","nc"]},"stype":"text"},{"label":"Lõppnäit","name":"Lnait","index":"Lnait","align":"right","searchoptions":{"sopt":["eq","ne","lt","le","gt","ge"]},"editoptions":{"maxlength":13,"dataEvents":[{"type":"change","fn":function(e) {dataChanged(e.target)}
},{"type":"focus","fn":function(e) {if(typeof e.target.ischanged=='undefined') {e.target.ischanged=false}}
}],"style":"text-align:right","readonly":null,"class":"jqgrid-inlineedit-element ","disabled":null},"editable":true,"width":74,"classes":null,"hidden":false},{"label":"Kogus","name":"Kogus","index":"Kogus","align":"right","searchoptions":{"sopt":["eq","ne","lt","le","gt","ge"]},"editoptions":{"maxlength":13,"dataEvents":[{"type":"change","fn":function(e) {dataChanged(e.target)}
},{"type":"focus","fn":function(e) {if(typeof e.target.ischanged=='undefined') {e.target.ischanged=false}}
}],"style":"text-align:right","readonly":null,"class":"jqgrid-inlineedit-element ","disabled":null},"editable":true,"width":71,"classes":null,"hidden":false},{"label":"Koguse jagamine","name":"Klassif1_nimetus","index":"Klassif1_nimetus","edittype":"select","editoptions":{"formatter":"select","value":":;R:Arvestuslik pind ;E:Elanike arvu järgi ;K:Korterite järgi ;:Kõigile sama ;V:Köetav pind ;P:Pindala järgi ","class":"ui-widget-content jqgrid-inlineedit-element","style":"width:100%;max-width:327px;height:130%","dataEvents":[{"type":"change","fn":function(e) {
updateSelectValue(this, 'Kogusx');
dataChanged(this);
}
},{"type":"keydown","fn":function(e) {
if(!enter(e)) return;
updateSelectValue(this, 'Kogusx');
dataChanged(this);
}
},{"type":"focus","fn":function(e) {if(typeof e.target.ischanged=='undefined') {e.target.ischanged=false}}
}]},"searchoptions":{"sopt":["cn","eq","ne","lt","le","gt","ge","bw","ew","nc"]},"editable":true,"width":109,"hidden":false},{"label":null,"name":"Kogusx","index":"Kogusx","editoptions":{"maxlength":1,"size":1,"dataEvents":[{"type":"change","fn":function(e) {dataChanged(e.target)}
},{"type":"focus","fn":function(e) {if(typeof e.target.ischanged=='undefined') {e.target.ischanged=false}}
}],"readonly":null,"class":"jqgrid-inlineedit-element ","disabled":null},"editable":true,"width":0,"classes":null,"hidden":true,"searchoptions":{"sopt":["cn","eq","ne","lt","le","gt","ge","bw","ew","nc"]},"stype":"text"}],
                //colModel,
                //sortName,
                emptyMsgDiv = $('<div style="display:none"><br/>&nbsp;&nbsp;Ei leia</div>');


        $grid = $("#grid");
        myColumnStateName = "Grnait.0.colState"; // 'Grnait.colState';
        myColumnsState = restoreColumnState(cm, myColumnStateName);
        isColState = typeof (myColumnsState) !== 'undefined' && myColumnsState !== null;
        idsOfSelectedRows = isColState && typeof (myColumnsState.selectedRows) !== "undefined" ?
                                    myColumnsState.selectedRows : [];
        urlFilters = isColState ? myColumnsState.filters : {};

        $grid.jqGrid({
            postData: { filters: urlFilters


                            },
            datatype: "json",

            rowNum: isColState ? myColumnsState.rowNum : 50,
            url: 'http://example.com/Grid/GetData?_entity=Grnait',
            colModel: cm,
                editurl: 'http://example.com/Grid/Edit?_entity=Grnait',


            beforeSelectRow: function (rowid, e) {
                var $this = $(this), rows = this.rows,
                  startId = $this.jqGrid('getGridParam', 'selrow'),
                  startRow, endRow, iStart, iEnd, i, rowidIndex,
                  colName = $.jgrid.getCellIndex($(e.target).closest('td')[0]),
               $self = $(this),
               savedRow = $self.jqGrid("getGridParam", "savedRow"),
               cmd = $grid.jqGrid('getGridParam', 'colModel');


                $("body").children("ul.ui-jqgrid-showHideColumnMenu").menu("destroy").remove();


                if (cmd[colName].name === 'cb' ) {
                    return true;
                }


                if (savedRow.length > 0 && savedRow[0].id !== rowid) {
                    //                if (typeof (lastSelectedRow) !== "undefined" && lastSelectedRow !== rowid) {
                    cancelEditing($grid);
                }

                if (!autoedit || ClickedInActionButton(e)) {
                    resetSelection();
                    return true;
                }


                if (lastSelectedRow !== rowid) {
                    jqGrid_editRow(rowid, afterGridSaveFunc, colName );

                    // PutFocus(e.target);
                }
                                PutFocus(e.target);
                return true;
            },




            ondblClickRow: function(rowId,iRow,iCol,e) {

                if (autoedit) {
                    return;
                }

                if (isInlineEdit()) {
                    return;
                }
                openDetail(rowId);
                PutFocus(e.target);
            },
            formDeleting: formDeletingTemplate
        });


        emptyMsgDiv.insertAfter($grid.parent());

        $grid.jqGrid('bindKeys', {
            scrollingRows: true,
            onEnter: openDetail
        }  );


        $grid.jqGrid("navGrid", "#grid_toppager", {
            edit: true
        },
        editParams,
       {
       },

    { 
    },
         searchParams
    ,
       {            }
                );

        var reloadWithNewFilterTemplate = function () {
            $grid.trigger('reloadGrid', [{current: true, page: 1}]);
        };
        GridCommon(false, 'Grnait',-1 );

    }); 

    function openDetail(rowId) {
        jqGrid_editRow(rowId, afterGridSaveFunc,false);
    }

    function addDocument() {
    }

    function onInlineEdit(rowId) {
        var savedRow = $grid.jqGrid("getGridParam", "savedRow");
        if (savedRow.length > 0 && savedRow[0].id !== rowId) {
            // if (rowId && rowId !== lastSelectedRow) {
                cancelEditing($grid);
            lastSelectedRow = rowId;
        }
    }

    function PutFocus(target) {
        $("input, select",target).select();
            }

    function afterGridSaveFunc(rowId, response) {
            aftersavefunc(rowId, response);
    }
</script>
<script type="text/javascript">
    function EditAddForm_AfterSubmit(response, postdata) {
        clearModeless();
        if (response.responseText.charAt(0) === '{') {
            var json = $.parseJSON(response.responseText);
                    postdata['Grupp'] = json.PrimaryKeyValues[0];
                    postdata['Kuu'] = json.PrimaryKeyValues[1];
                    postdata['Toode'] = json.PrimaryKeyValues[2];
            return [true, '', json.Id];
        }
        alert( decodeErrorMessage(response.responseText, '', ''));
        return [false, decodeErrorMessage(response.responseText, '', ''), null];
    }


    var afterSaveFuncAfterAdd = function(rowId, response) {
        var data = $.parseJSON(response.responseText);
        $(this).jqGrid('setRowData', rowId, { Grupp: data.PrimaryKeyValues[0] });
        cancelEditing($grid);
     afterGridSaveFunc(rowId,response);
        jqXHRFromOnSuccess=null;
    };


    $.extend(true,
    $.jgrid.inlineEdit, {

        position: "beforeSelected",
        focusField: false,
        restoreAfterError: false,
        afterrestorefunc: function(rowId) {
            updateButtonState($grid, rowId);
            setFocusToGrid();
            lastSelectedRow = undefined;
        },
        aftersavefunc: function(rowId, response) {
            afterSaveFuncAfterAdd(rowId, response);
        },
        oneditfunc: function(rowId) {
            onInlineEdit(rowId);
            updateButtonState($grid, rowId);
        },
        keys: true,
        rowID: '_empty',
        useDefValues: true,
        extraparam: { _dokdata: getEevaFormData },
        errorfunc: errorfunc
    });
</script>
    <div id="grid1container" style="width: 100%; height: 100%">
        <table id="grid"></table>
    </div>
        </div>
    </div>
</body>
</html>

更新

我根据答案添加了 afterComplete 并验证了正确的 id 已传递给 attr()。问题依然存在。在第二种形式或内联编辑中,错误的密钥仍然传递给服务器。 我在下面更新了测试用例。

看来你想在编辑后更改该行的rowid。您使用 prmNames: { id: "_rowid", ...} 选项将编辑数据发送到服务器。所以postdata._rowid应该包含编辑行的rowid。编辑后服务器的响应看起来像

{"PrimaryKeyValues":["1","change","004"],"Id":"1ä_63_68_61_6E_67_65ä004"}

其中 Id 属性 在编辑行后包含 new rowid。在这种情况下,您可以使用 afterComplete 回调

afterComplete: function (jqXhr, postdata, $form, formOper) {
    if (formOper !== "add") {
        var json = $.parseJSON(jqXhr.responseText),
            p = $(this).jqGrid("getGridParam"),
            oldId = p.idPrefix + postdata._rowid,
            newId = p.idPrefix + json.Id,
            i;
        $("#" + $.jgrid.jqID(oldId)).attr("id", newId);
        if (p.selrow === oldId) {
            p.selrow = newId;
            i = $.inArray(oldId, p.selarrrow);
            if (i >= 0) {
                p.selarrrow[i] = newId;
            }
        }
    }
}

您应该在用于表单编辑的 editParams 中包含此类回调:

var editParams =  {
    afterSubmit: function (response, postdata) {
        return EditAddForm_AfterSubmit(response, postdata);
    },
    afterComplete: function (jqXhr, postdata, $form, formOper) {
        if (formOper !== "add") {
            var json = $.parseJSON(jqXhr.responseText),
                p = $(this).jqGrid("getGridParam"),
                oldId = p.idPrefix + postdata._rowid,
                newId = p.idPrefix + json.Id,
                i;
            $("#" + $.jgrid.jqID(oldId)).attr("id", newId);
            if (p.selrow === oldId) {
                p.selrow = newId;
                i = $.inArray(oldId, p.selarrrow);
                if (i >= 0) {
                    p.selarrrow[i] = newId;
                }
            }
        }
    },
    url: 'http://example.com/Edit?_entity=Grnait',
    closeAfterEdit: true,
};