【问题标题】:Add/edit/delete a row in free jqGrid在免费 jqGrid 中添加/编辑/删除一行
【发布时间】:2016-02-20 07:40:15
【问题描述】:

我正在使用免费的 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”进行服务器端调用。 那么我如何在添加/编辑/删除行时进行服务器端调用,并将参数传递给这些调用。如果有人能指出我在某个地方的工作示例,我将不胜感激。谢谢

更新:-

我已删除“操作”格式化程序并修改代码如下所示,

<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}
]

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

更新 2:-

在使用以下代码在添加/编辑行上调用服务器端代码之前,我可以成功设置请求标头,

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

更新 3:-
根据 Oleg 的建议清理代码,如下所示。但在严格模式下,我现在收到 JS 错误 - “未捕获的 ReferenceError:未定义保存参数”

<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>

【问题讨论】:

    标签: javascript jquery jqgrid free-jqgrid


    【解决方案1】:

    您应该检查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

    你写道你想使用 both formater: "actions"inlineNav. 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 usingformatter: "actions"andnavGridtogether. The usage of inline editing have very close problems. You will have to provideaddParamsandeditParamsproperties ofinlineNav and the corresponding options offormatter:“动作”`(见here)。为了让代码更易读、更简单,免费的 jqGrid 提供了另一种形式的编辑选项。

    您可以在 jqGridinlineEditing 选项内指定所有内联编辑选项,inlineNav 方法的附加特定选项(如果需要)在 navOptionsinlineNavOptions 中,选项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"} 将在编辑和删除中使用的默认id 属性重命名为EmpId。因此,在删除和编辑操作期间,jqGrid 将自动将带有来自_id 列的值的EmpId 参数发送到服务器。

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

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

    【讨论】:

    • 感谢您的详细回复。我将根据您的建议审查我的示例代码并让您知道。顺便说一句,我只是想通过使用这里文章中的代码来使行添加/编辑工作 - codeproject.com/Articles/610359/JqGrid-Inline-Editing。一旦它工作,我将在我的应用程序中使用相同的方法。
    • @ivish:来自 codeproject.com 的示例远非好。查看the answer发布从您的服务器返回的 JSON 数据示例。您需要在所有编辑请求中使用 RESTful 编辑还是使用 HTTP POST?
    • @ivish:如果您使用 ASP.NET,那么我为 the answer 创建的 the demo project 对您来说也可能很有趣。
    • 你好奥列格,我在我的问题中添加了一个“更新”。截至目前,我在所有编辑请求中只需要 HTTP POST。我在服务器端使用 spring/java。不过非常感谢分享 ASP.NET 演示项目。我正在浏览项目的 javascript 部分,看看如何实现编辑。
    • @jeffery_the_wind:不客气!我也发现选项inlineEditingformDeletingformEditingformViewingsearchingreloadGridOptionsnavOptionsactionsNavOptionsinlineNavOptions 简化了 jqGrid 的维护并使代码更简短易读。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-15
    • 2014-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多