代码之家  ›  专栏  ›  技术社区  ›  ReynierPM

如何在内联编辑后将数据发送到服务器?

  •  0
  • ReynierPM  · 技术社区  · 6 年前

    我免费使用jQgrid( release 4.15.2 )我需要添加内联编辑行的功能,这根本不是问题,因为它很容易设置。以下是我使用的代码:

    $.jgrid = $.jgrid || {};
    $.jgrid.no_legacy_api = true;
    $.jgrid.useJSON = true;
    
    $(function () {
        "use strict";
    
        var $grid = $("#list"),
            pagerSelector = "#pager",
            customAddButton = function (options) {
                $grid.jqGrid('navButtonAdd', pagerSelector, options);
                $grid.jqGrid('navButtonAdd', '#' + $grid[0].id + "_toppager", options);
            };
    
        $.fn.fmatter.customActionsFormatter = function (cellValue, options, rowData) {
            return '<a href="#" title="Delete selected row"><span class="fa fa-fw fa-trash-o delete_row" data-id="' + rowData.Id + '"></span></a>';
        };
    
        $grid.jqGrid({
            url: '/ajax/plans_to_forms/get_all',
            datatype: "json",
            colNames: ["", "Id", "Form #", "Form", "Plan", "Class", "Drug"],
            colModel: [
                {name: "act", formatter: "customActionsFormatter", width: 20, search: false},
                {name: "Id", jsonmap: "Id", key: true, hidden: true},
                {name: "FormId", align: 'center', fixed: true, frozen: true, resizable: false, width: 100},
                {name: "FormName", width: 300},
                {name: "PlanName", width: 300},
                {name: "DrugGroupName", width: 300},
                {name: "DrugName", width: 300}
            ],
            cmTemplate: {autoResizable: true, editable: true},
            iconSet: "fontAwesome",
            rowNum: 25,
            guiStyle: "bootstrap",
            autoResizing: {compact: true},
            rowList: [25, 50, 100, "10000:All"],
            viewrecords: true,
            autoencode: true,
            sortable: true,
            pager: pagerSelector,
            toppager: true,
            cloneToTop: true,
            hoverrows: true,
            multiselect: true,
            multiPageSelection: true,
            rownumbers: true,
            sortname: "Id",
            sortorder: "desc",
            loadonce: true,
            autowidth: true,
            autoresizeOnLoad: true,
            forceClientSorting: true,
            shrinkToFit: true,
            navOptions: {
                edit: false,
                add: false,
                del: false,
                search: false
            },
            inlineEditing: {keys: true, defaultFocusField: "DrugGroupName", focusField: "DrugGroupName"},
            onSelectRow: function (rowid, status, e) {
                var $self = $(this), savedRow = $self.jqGrid("getGridParam", "savedRow");
    
                if (savedRow.length > 0 && savedRow[0].id !== rowid) {
                    $self.jqGrid("restoreRow", savedRow[0].id);
                }
    
                $self.jqGrid("editRow", rowid, {focusField: e.target});
            }
        }).jqGrid('navGrid', pagerSelector, {
            search: false,
            edit: false,
            add: false,
            del: false,
            refresh: true,
            cloneToTop: true
        }).jqGrid("filterToolbar", {
            stringResult: true, searchOnEnter: false, defaultSearch: 'cn'
        }).jqGrid("gridResize").jqGrid('setFrozenColumns');
    
        customAddButton({
            caption: 'Delete selected',
            buttonicon: 'fa-trash-o',
            title: "Delete all selected rows",
            onClickButton: function () {
                var rowIds = $("#list").jqGrid('getGridParam', 'selarrrow');
    
                if (rowIds.length > 0) {
                    delete_all_link_modal.modal();
                    delete_all_link_modal.attr('data-link-ids', rowIds);
                } else {
                    alert('You must select at least one item.');
                }
            }
        });
    });
    

    以下行启用内联编辑:

    inlineEditing: {keys: true, defaultFocusField: "DrugGroupName", focusField: "DrugGroupName"}
    

    我的问题在哪里?我只需要编辑列 DrugGroupName 上面的一行使整行可编辑,这就引出了以下问题:

    • 是否可以只编辑一组给定的列,而不编辑所有列?-我在检查文件 here 但我找不到任何有用的东西

    • 只要我在任何其他地方单击或按ENTER键,就可以将数据发送到服务器?-我想避免额外点击保存图标。

    更新: 我已经找到了我第一个问题的答案。我只需要在定义 colModel . 前任:

    colModel: [
        {name: "act", formatter: "customActionsFormatter", width: 20, search: false},
        {name: "Id", jsonmap: "Id", key: true, hidden: true},
        {name: "FormId", align: 'center', fixed: true, frozen: true, resizable: false, width: 100, editable: false},
        {name: "FormName", width: 300, editable: false},
        {name: "PlanName", width: 300, editable: false},
        {
            name: "DrugGroupName",
            width: 300,
            edittype: "select",
            editoptions: {
                generateValue: true,
                selectFilled: function (options) {
                    setTimeout(function () {
                        $(options.elem).select2({
                            width: "100%"
                        });
                    }, 0);
                }
            },
            stype: "select", searchoptions: {
                sopt: ["eq", "ne"],
                generateValue: true,
                noFilterText: "Any",
                selectFilled: function (options) {
                    $(options.elem).select2({
                        width: "100%"
                    });
                }
            }
        },
        {name: "DrugName", width: 300, editable: false}
    ]
    

    那样的话我是在强迫 药物组名称 是唯一可编辑的。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Oleg    6 年前

    我认为你的代码有很多小问题。我准备了演示 https://jsfiddle.net/OlegKi/rmo2370r/19/ ,它将修复大多数问题,并演示select2的用法和免费jqGrid的一些特性。

    第一个小问题是使用正确的rowid。使用当前隐藏列

    {name: "Id", jsonmap: "Id", key: true, hidden: true}
    

    这是使用jqGrid的用户的典型误解。Rowid将另存为 id 行的属性( <tr> 元素)。看见 the picture . 不需要将案例信息隐藏起来 <td> 网格内的元素。相反,您可以使用以下jqGrid选项

    prmNames: { id: "Id" },
    jsonReader: { id: "Id" },
    

    相反选项 jsonReader.id 在填充网格期间通知jqGrid从何处获取rowid,并 prmNames.id 在编辑网格期间提供id的名称。

    要在JSFiddle中填充jqGrid,可以使用Echo服务:

    url: '/echo/json/',
    datatype: 'json',
    mtype: 'POST', // required for '/echo/json/'
    postData: {
        json: JSON.stringify(mydata)
    },
    

    对URL的请求 /echo/json/ mydata 作为回应。可以使用Chrome/IE/Firefox开发工具的网络选项卡来详细检查HTTP流量。

    以同样的方式

    editurl: '/echo/json/',
    formDeleting: {
        url: '/echo/json/',
        ...
    }
    

    用于内联编辑和表单删除。

    接下来的变化。我补充道 resetWidthOrg: true 中的属性 autoResizing :

    autoResizing: {
        compact: true,
        resetWidthOrg: true
    }
    

    改变了工作结果 autowidth: true 结合 autoresizeOnLoad: true . 您可以看到,所有列的宽度都是基于列的内容的,比以前好得多。看见 the issues 了解更多详细信息。

    我不明白 customActionsFormatter . 我将其替换为标准格式化程序操作

    { name: "act", template: "actions" }
    

    免费jqGrid允许在需要时非常轻松地自定义操作按钮。看见 the answer the wiki article 了解更多详细信息。

    使用的旧代码

    cmTemplate: {
      autoResizable: true,
      editable: true
    }
    

    和设置 editable: false 在most列中。相反,您只需删除 editable: true 从…起 cmTemplate 添加 可编辑:true 仅在一列中,您需要编辑该列,并将其包括在 cmTemplate模板 其他常用设置 colModel :

    cmTemplate: {
        width: 300,
        autoResizable: true
    }
    

    许多其他代码也可以简化。参见修改后的代码 onSelectRow 例如

    要自定义删除对话框,可以使用以下设置:

    formDeleting: {
        url: '/echo/json/', // '/ajax/plans_to_forms/delete/' in final solution
        width: 320,
        caption: 'Delete Plan to Form Link',
        msg: 'Are you sure you want to delete this link?',
        beforeShowForm: function ($form) {
            var rowids = $form.find("#DelData>td").data("rowids");
                console.log(rowids);
                if (rowids.length > 1) {
                $form.find("td.delmsg")
                        .html('Are you sure you want to delete all the selected form links?');
                }
        }
    }
    

    删除发送数据 Id=20622,20626 oper=del 到服务器( formDeleting.url ). 可以使用 serializeDelData 如果需要,将数据转换为JSON。

    要在编辑期间从列向服务器发送更多数据,可以添加 editable: "hidden" 在某列中。我在中添加了属性 FormId 演示列和编辑期间发送到服务器的数据如下所示

    {"FormId":"3393","DrugGroupName":"Some other value","oper":"edit","Id":"20620"}
    

    填写的数据 <select> 对于服务器的其他Ajax请求,需要使用 editoptions.dataUrl . 我在演示中添加了 editoptions.postData 要仅模拟对服务器的实际请求,请执行以下操作:

    editoptions: {
        dataUrl: "/echo/json/",
        postData: {
            json: JSON.stringify([
                    "Non-Specialty Medications",
                    "General Pharmacy Authorization",
                    "Some other value"
                ])
            },
            buildSelect: function (data) {
                var select = "<select>", i;
    
                for (i = 0; i < data.length; i++) {
                    select += "<option value='" + String(data[i]).replace(/\'/g, "&#39;") +
                                "'>" + $.jgrid.htmlEncode(data[i]) + "</option>"
                }
                return select + "</select>";
            },
            selectFilled: function(options) {
                var $self = $(this);
    
                setTimeout(function() {
                    $(options.elem).select2({
                        width: "100%"
                    }).on('select2:select', function (e) { 
                        // save the data on selection
                        $self.jqGrid("saveRow", options.rowid);
                    });
                }, 0);
            }
        },
        stype: "select",
        searchoptions: {
            sopt: ["eq", "ne"],
            generateValue: true,
            noFilterText: "Any",
            selectFilled: function(options) {
                $(options.elem).select2({
                    width: "100%"
                });
            }
        }
    }
    

    上述请求 dataUrl 返回JSON字符串 [ "Non-Specialty Medications", "General Pharmacy Authorization", "Some other value" ] buildSelect 使用将数据转换为HTML片段 <选择(>); 包含所有 <options> . 由此产生的 <选择(>); 将转换为select2 CONTROL内的 selectFilled 回拨。最后,代码使用

    ajaxSelectOptions: {
        type: "POST",
        dataType: "json"
    }
    

    将Ajax请求的参数更改为的选项 数据URL . 演示 https://jsfiddle.net/OlegKi/rmo2370r/19/ 包含其他一些小更改,如删除不必要的空寻呼机div和 pager: true 就像你已经用过的一样 toppager: true . 这是我在免费jqGrid fork中实现的另一个特性,以简化jqGrid的使用。