Add/edit/delete 免费 jqGrid 中的一行

Add/edit/delete a row in free jqGrid

我正在使用免费的 jqGrid 4.12.1。我想在网格中添加、编辑和删除行,并希望为每个操作进行服务器端调用。 我添加了 editurl 和 'actions' 格式化程序,如下所示,

 {
  name: "actions",
  width: 100,
  formatter: "actions",
  formatoptions: {
      keys: true,
      editOptions: {},
      addOptions: {},
      delOptions: {}
  }       
  }

我正在添加 'inlineNav' 如下,

$("#itemList").jqGrid('inlineNav',"#itemListPager", 
         {
            edit: true,
            add: true,
            del: true,
            search: true,
            searchtext: "Search",
            addtext: "Add",
            edittext: "Edit",
            deltext: "Delete"
        },
        {  
            closeOnEscape: true, //Closes the popup on pressing escape key
            reloadAfterSubmit: true,
            drag: true,
            url: "${pageContext.request.contextPath}/billing/saveItem",
            errorfunc: function (rowId, resp) {
                alert(resp);
            },
            afterSubmit: function (response, postdata) {
                if (response.responseText == "") {

                    $(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid'); //Reloads the grid after edit
                    return [true, '']
                }
                else {
                    $(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid'); //Reloads the grid after edit
                    return [false, response.responseText]//Captures and displays the response text on th Edit window
                }
            },
            editData: {
                EmpId: function () {
                    var sel_id = $('#itemList').jqGrid('getGridParam', 'selrow');
                    var value = $('#itemList').jqGrid('getCell', sel_id, '_id');
                    return value;
                }
            }
        },
        {
            closeAfterAdd: true, //Closes the add window after add
            url: "${pageContext.request.contextPath}/billing/saveItem",
            afterSubmit: function (response, postdata) {
                if (response.responseText == "") {

                    $(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid')//Reloads the grid after Add
                    return [true, '']
                }
                else {
                    $(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid')//Reloads the grid after Add
                    return [false, response.responseText]
                }
            }
        },
        {   //DELETE
            closeOnEscape: true,
            closeAfterDelete: true,
            reloadAfterSubmit: true,              
            url: "${pageContext.request.contextPath}/billing/saveItem",
            drag: true,
            afterSubmit: function (response, postdata) {
                if (response.responseText == "") {

                    $("#itemList").trigger("reloadGrid", [{ current: true}]);
                    return [false, response.responseText]
                }
                else {
                    $(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid');
                    return [true, response.responseText]
                }
            },
            delData: {
                EmpId: function () {
                    var sel_id = $('#itemList').jqGrid('getGridParam', 'selrow');
                    var value = $('#itemList').jqGrid('getCell', sel_id, '_id');
                    return value;
                }
            }
        },
        {//SEARCH
            closeOnEscape: true
        }       
        );

上面添加的 'inlineNav' 没有效果,因为在添加新行或删除现有行时没有进行服务器端调用。服务器端调用仅在编辑的情况下进行,并且该调用也不会通过上面的 'inlineNav' 代码发生。因为即使我删除 'inlineNav' 代码,服务器端调用仍然对 'editurl' 进行。 那么我如何在 adding/editing/deleting 行上进行服务器端调用并将参数传递给这些调用。如果有人能指出我在某处的工作示例,我将非常感激。谢谢

更新:-

我删除了 'actions' 格式化程序并将代码修改为如下所示,

<script type="text/javascript">

var dataGrid = $('#itemList');
var firstClick = true;
    $(document).ready(function () {
        $('#action').click(function () {
            if (!firstClick) {
                $("#itemList").setGridParam({datatype:'json'}).trigger("reloadGrid");
            }   
            firstClick = false;
        $("#itemList").jqGrid({
            url: "${pageContext.request.contextPath}/billing/medicines",
            datatype: "json",
            //styleUI : 'Bootstrap',
            mtype: "POST",
            autowidth: true,
            shrinkToFit: true,
            sortname: "Id",
            sortorder: "asc",
            loadBeforeSend: function(jqXHR) {
                 jqXHR.setRequestHeader("X-CSRF-TOKEN", $("input[name='_csrf']").val());
            },
            postData: {
            },
            loadError: function (jqXHR, textStatus, errorThrown) {
                alert('HTTP status code: ' + jqXHR.status + '\n' +
                      'textStatus: ' + textStatus + '\n' +
                      'errorThrown: ' + errorThrown);
                alert('HTTP message body (jqXHR.responseText): ' + '\n' + jqXHR.responseText); 
            },
            colNames: ["Id", "Item Type", "Item Code", "Unit", "Stock", "Batch No.", "Expiry Date", "Quantity Per Unit", "Price"],
            colModel: [
                { name: "itemId", width: 35, align: "left", sorttype:"int", search: false},
                { name: "itemType", width: 100, align: "left",  editable: true},
                { name: "itemCode", width: 120, align: "left",  editable: true},
                { name: "unit", width: 70, align: "left", search: false,  editable: true},
                { name: "availableQuantity", width: 55, align: "left", search: false, formatter: "number",  editable: true},
                { name: "batchNumber", width: 80, align: "left", search: false,  editable: true},
                { name: "expiryDate", width: 80, align: "left", search: false, sorttype: "date",  editable: true, formatoptions: {srcformat:'d/m/Y', newformat:'d/m/Y'}},
                { name: "quantityPerUnit", width: 80, align: "left", search: false, formatter: "number",  editable: true},
                { name: "price", width: 55, align: "left", search: false, formatter: "number",  editable: true}
            ],
            pager: "#itemListPager",
            rowNum: 50,
            rowList: [50, 100, 150, 200],
            rownumbers: true,
            rownumWidth: 25,
            sortname: "id",
            sortorder: "desc",
            viewrecords: true,
            height: '100%',
            loadonce: true,
            //gridview: true,
            autoencode: true,
            editurl: "${pageContext.request.contextPath}/billing/saveItem",
            caption: "Item List",
            ondblClickRow: function(rowId){}
        }).navGrid('#itemListPager',{add:false,edit:false,del:true});
        $("#itemList").jqGrid('filterToolbar', {autoSearch: true, stringResult: true, searchOnEnter: false, defaultSearch: 'cn'});
        $("#itemList").jqGrid('gridResize', { minWidth: 450, minHeight: 150 });

        var saveparameters = {
                "successfunc" : null,
                "url" : "${pageContext.request.contextPath}/billing/saveItem",
                    "extraparam" : {},
                "aftersavefunc" : null,
                "errorfunc": null,
                "afterrestorefunc" : null,
                "restoreAfterError" : true,
                "mtype" : "POST"
            };

        var editparameters = {
                "keys" : false,
                "oneditfunc" : null,
                "successfunc" : null,
                "url" : "${pageContext.request.contextPath}/billing/editItem",
                    "extraparam" : {},
                "aftersavefunc" : null,
                "errorfunc": null,
                "afterrestorefunc" : null,
                "restoreAfterError" : true,
                "mtype" : "POST"
            };

        var parameters = { 
                   edit: true,
                   editicon: "ui-icon-pencil",
                   add: true,
                   addicon:"ui-icon-plus",
                   save: true,
                   saveicon:"ui-icon-disk",
                   cancel: true,
                   cancelicon:"ui-icon-cancel",
                   addParams : saveparameters,
                   editParams : editparameters
                };
        $("#itemList").jqGrid('inlineNav',"#itemListPager", parameters);

    });
});
</script> 

样本json达达是,

[
{"itemDetailId":1,"itemId":1,"itemType":"Medicine","itemCode":"Aler-Dryl","itemDesc":"Aler-Dryl","batchNumber":"batch1","expiryDate":"18/02/2017","unit":"tablet","subUnit":"tablet","availableQuantity":120.0,"quantityPerUnit":60.0,"price":122.0},
{"itemDetailId":2,"itemId":2,"itemType":"Medicine","itemCode":"Benadryl","itemDesc":"Benadryl","batchNumber":"batch1","expiryDate":"18/02/2017","unit":"ml","subUnit":"ml","availableQuantity":60.0,"quantityPerUnit":120.0,"price":90.0}
]

现在,编辑参数和保存参数中指定的 url 分别在编辑和添加行时被调用。 如果上述方法是好的,请提出建议。此外,我们如何在编辑或保存数据发布到服务器之前设置请求 header。而且我找不到类似于 editparameters 和 saveparameters 的 deleteparameters 之类的东西,因此我可以使用 delete 特定参数。

更新 2:-

我可以在使用以下代码在 add/edit 行上调用服务器端代码之前成功设置请求 header,

 $.ajaxSetup({
            beforeSend: function (jqXHR, settings) {                     
               jqXHR.setRequestHeader("X-CSRF-TOKEN", $("input[name='_csrf']").val());
          }});

更新 3:-
按照 Oleg 的建议清理代码如下。但是在严格模式下,我现在遇到 JS 错误 - "Uncaught ReferenceError: saveparameters is not defined"

<script type="text/javascript">
$(document).ready(function () {
    "use strict";
    var dataGrid = $('#itemList');
    var firstClick = true;
    $('#action').click(function () {
        if (!firstClick) {
            $("#itemList").setGridParam({datatype:'json'}).trigger("reloadGrid");
        }   
        firstClick = false;
    $("#itemList").jqGrid({
        url: "${pageContext.request.contextPath}/billing/medicines",
        datatype: "json",
        mtype: "POST",
        autowidth: true,
        loadBeforeSend: function(jqXHR) {
             jqXHR.setRequestHeader("X-CSRF-TOKEN", $("input[name='_csrf']").val());
        },
        colNames: ["Id", "Item Type", "Item Code", "Unit", "Stock", "Batch No.", "Expiry Date", "Quantity Per Unit", "Price"],
        colModel: [
            { name: "itemId", width: 35, align: "left", sorttype:"int", search: false, editable: false, key: true},
            { name: "itemType", width: 100, align: "left"},
            { name: "itemCode", width: 120, align: "left"},
            { name: "unit", width: 70, align: "left", search: false},
            { name: "availableQuantity", width: 55, align: "left", search: false, formatter: "number",},
            { name: "batchNumber", width: 80, align: "left", search: false},
            { name: "expiryDate", width: 80, align: "left", search: false, sorttype: "date", formatoptions: {srcformat:'d/m/Y', newformat:'d/m/Y'}},
            { name: "quantityPerUnit", width: 80, align: "left", search: false, formatter: "number"},
            { name: "price", width: 55, align: "left", search: false, formatter: "number"}
        ],
        cmTemplate: {editable: true},
        pager: true,
        rowNum: 50,
        rowList: [50, 100, 150, 200],
        rownumbers: true,
        rownumWidth: 25,
        sortname: "itemType",
        sortorder: "asc",
        forceClientSorting: true,
        viewrecords: true,
        height: '100%',
        loadonce: true,
        //gridview: true,
        autoencode: true,
        editurl: "${pageContext.request.contextPath}/billing/saveItem",
        caption: "Item List"
        //ajaxRowOptions: { beforeSend: myTokenSetting }, loadBeforeSend: myTokenSetting where var myTokenSetting = function(jqXHR) { jqXHR.setRequestHeader("X-CSRF-TOKEN", $("input[name='_csrf']").val()); }
    }).navGrid({add:false,edit:false,del:true});
    $("#itemList").jqGrid('filterToolbar', {autoSearch: true, stringResult: true, searchOnEnter: false, defaultSearch: 'cn'});
    $("#itemList").jqGrid('gridResize', { minWidth: 450, minHeight: 150 });

    var saveparameters = {
            "successfunc" : null,
            "url" : "${pageContext.request.contextPath}/billing/saveItem",
             "extraparam" : {},
            "aftersavefunc" : null,
            "errorfunc": null,
            "afterrestorefunc" : null,
            "restoreAfterError" : true,
            "mtype" : "POST"
        };

    var editparameters = {
            "keys" : false,
            "oneditfunc" : null,
            "successfunc" : null,
            "url" : "${pageContext.request.contextPath}/billing/editItem",
             "extraparam" : {},
            "aftersavefunc" : null,
            "errorfunc": null,
            "afterrestorefunc" : null,
            "restoreAfterError" : true,
            "mtype" : "POST"
        };

    var parameters = { 
               edit: true,
               editicon: "ui-icon-pencil",
               add: true,
               addicon:"ui-icon-plus",
               save: true,
               saveicon:"ui-icon-disk",
               cancel: true,
               cancelicon:"ui-icon-cancel",
               addParams : saveparameters,
               editParams : editparameters
            };
    $("#itemList").jqGrid('inlineNav',parameters);

    $.ajaxSetup({
        beforeSend: function (jqXHR, settings) {
           alert('Before Row Send');         
           jqXHR.setRequestHeader("X-CSRF-TOKEN", $("input[name='_csrf']").val());
      }});

    });
});
</script>

您应该检查 inlineNav 的选项以发现您使用了完全错误的选项:

jQuery("#grid_id").jqGrid('inlineNav', pagerid, parameters);

其中 parameters 的形式为

{ 
    edit: true,
    editicon: "ui-icon-pencil",
    add: true,
    addicon: "ui-icon-plus",
    save: true,
    saveicon: "ui-icon-disk",
    cancel: true,
    cancelicon: "ui-icon-cancel",
    addParams: {useFormatter : false},
    editParams: {}
}

您使用了另一个方法的选项navGrid

jQuery("#grid_id").jqGrid('navGrid', '#gridpager', {parameters},
    prmEdit, prmAdd, prmDel, prmSearch, prmView);

允许使用 form editing.

你写道你想同时使用formater: "actions"</code>inlineNav<code>. Thus you would have to provide some options of inline editing twice. I would recommend you to read [the wiki article](https://github.com/free-jqgrid/jqGrid/wiki/New-style-of-usage-options-of-internal-methods). It describes the problems with the usage of form editing using格式化程序:"actions"andnavGridtogether. The usage of inline editing have very close problems. You will have to provideaddParamsandeditParamsproperties ofinlineNavand the corresponding options of格式化程序:"actions"`(参见here)。为了使代码更具可读性和简单性,免费的 jqGrid 提供了另一种形式的编辑选项。

您可以在 jqGridinlineEditing 选项中指定所有内联编辑选项,在 [=] 中指定 inlineNav 方法(如果需要)的其他特定选项24=]或inlineNavOptions中删除操作的选项formDeleting等。此外 reloadGrid 有选项 fromServer: true 来恢复 datatype 的原始值("json""jsonp""xml"、...)用过的。您可以使用表单编辑的 reloadGridOptions: { fromServer: true } 选项或 formDeleting 强制从服务器重新加载。

此外,您现有的代码包含许多非常可疑的部分 _idEmpId。我强烈建议您包含用于填充网格 输入 JSON 数据的格式示例 。如果您想使用 EmpId 作为 rowid 的名称,为什么要使用 _id 呢?代码片段如

EmpId: function () {
    var sel_id = $('#itemList').jqGrid('getGridParam', 'selrow');
    var value = $('#itemList').jqGrid('getCell', sel_id, '_id');
    return value;
}

显示当前的 rowid 似乎是错误的并且 _id 列包含您需要的正确信息作为名称 EmpId.

下的 rowid

例如,您可以使用 prmNames: { id: "EmpId"} 并将 key: true 添加到列 _id_id 列中的 属性 key: true 将通知 jqGrid 使用 _id 列中的值作为 rowid 并且 prmNames: { id: "EmpId"} 将重命名为 default id 属性用于编辑和删除到EmpId。因此jqGrid将自动发送EmpId参数,在删除和编辑操作期间_id列的值到服务器。

也许您也可以从网格中删除不需要的列 _id(至少如果您隐藏该列),但我需要查看 jqGrid 的 输入数据说你可以使用的 jqGrid 的确切选项。

我确信您可以使用免费的 jqGrid 选项从根本上减少现有代码并使其更具可读性,但您必须仔细检查现有代码。我建议您从使用正确的 rowid 和消除您使用的所有隐藏列开始。 free jqGrid提供了additionalProperties的特性,其结构与colModel的结构非常接近,但是输入数据对应的属性只会保存在本地数据中,不会放在DOM中table。如果您 post 您现有的 colModeljsonReader 和从服务器返回的 JSON 响应示例(1-2 行数据和虚拟数据),我可以解释得更清楚就足够了)。