仅在客户端上使用模态形式向 jqGrid 添加新行

发布于 2024-10-31 13:20:20 字数 3023 浏览 4 评论 0 原文

似乎有很多解决方案非常接近解决我的问题,但在我提出的数十个问题中,似乎没有一个能够完全解决我想要做的事情。尽管我看到几乎同样的问题没有得到答案。我尝试了很多选项和功能的组合,但都无济于事。

我想使用模态表单将包含输入值的新行添加到 jqGrid,但我不希望它在提交时发布到服务器。我确实想最终发布到服务器,但只有在客户端用户对从模式表单添加的行执行额外编辑(如果需要)之后。在客户端执行一些编辑(进而动态更新其他列)之前,我不希望将任何行保存到远程数据库。一旦验证了值的特定状态,就会显示“保存”按钮,并且可以将网格行发布到服务器。除非满足此验证条件,否则不会将行提交到数据库。我在我的应用程序的其他地方使用了许多 jqGrid,它们确实发布了提交的模式表单的新行数据,但是我试图在这个网格中完成一些与客户端不同的事情,而客户端不会立即涉及服务器。我喜欢模式表单的更直观的界面,用于与客户端用户初始输入值,然后在需要时编辑内联新行的字段,这就是我的问题所必需的:我可以仅将表单作为新行提交吗?发生向服务器发送任何操作吗?

我在 jqGrid Wiki 资源中看到用户发表的评论,他说如果“clientArray”是为使用 Grids 模态表单提交选项而输入的值“editurl:”clientArray”,则模态表单不会吐出“未设置 URL” ”消息,但它仍然存在,并且新行未添加到网格中。我已将网格数据类型设置为本地“数据类型:'clientSide'”,但得到相同的“未设置 URL”错误消息。脚本是对于由自定义按钮调用的模态表单来说非常简单,如下所示:(

“footerrow、userDataOnFooter 和 altRows”选项作为摘要页脚中更新值的一部分包含在内,这与对新的单元格执行的编辑有关通过模态形式添加行)

jQuery("#grid_test").jqGrid({
    url:'/grid_test_url.asp?id=' + vId,
    datatype: "clientSide",
    colNames: ['ID','Col 1', 'Col 2', 'Col 3','Col 4'],
    colModel: [

        {name:'id',index:'id',width:90,align:"center",editable:true,editoptions:{size:25}, formoptions: {...}, editrules: {...}},
        {name:'col1',index:'col1',width:130,align:"right",editable:true,editoptions:{size:25}, formoptions: {}, editrules: {}},
        {name:'col2',index:'col2',width:130,align:"right",editable:true,editoptions:{size: 25}, formoptions: {}, editrules: {}},
        {name:'col3',index:'col3',width:130,align:"right",editable: true,editoptions:{size:25}, formoptions: {}, editrules: {}},
        {name:'col4',index:'col4',width:130,align:"right",editable:true,editoptions:{ size: 25 }, formoptions: {}, editrules: {}}   

    ],
    rowNum:5,
    rowList:[5,10,20],
    pager: '#pgrid_test',
    toolbar: [true, "top"],
    editurl: '', //not sure what would go here to block attempted post by the Submit action of the modal form
    width: 500,
    sortname: 'id',
    viewrecords: true,
    sortorder: "asc",
    multiselect: true,
    cellEdit: true,
    caption: "Grid Test Add New Row",
    footerrow: true, 
    userDataOnFooter: true,
    altRows: true
})
jQuery("#grid_test").jqGrid('navGrid', '#pgrid_test', { add: false, edit: false, del: false })

//append custom button
$("#t_grid_test").append("<input type='button' class='add' value='Add New Row' style='height:20px; color:green; font-size:11px;' />");

$("input.add", "#t_grid_test").click(function () {
    jQuery("#grid_test").jqGrid('editGridRow', "new", {
        jqModal: true,
        savekey: [true, 13],
        navkeys: [true, 38, 40],
        bottominfo: "Fields marked with (*) are required. ",
        addCaption: 'New Row Values',
        width: 300,
        dataheight: 200,
        recreateForm: true,

      //checkOnUpdate: true,
      //checkOnSubmit: true,
      //reloadAfterSubmit: true,
        closeOnEscape: true,
        closeAfterAdd: true
        //clearAfterAdd: true
    })
});

我希望这相当清楚,使用模态形式添加一行而不立即发布到服务器应该相当简单,但我无法找到解决方案。如果我没有立即单击图标以获得正确的答案,请耐心等待,但当我知道要单击什么时,我会这样做,因此请相应地提出建议。 :) 非常感谢。 杰瑞

There appear to be many solutions that are very close to addressing my problem but of the dozens and dozens of questions I've poured through not one seems to exactly address what I'm trying to do. Although I have seen nearly the same question asked without an answer. I have tried so many combinations of options and functions to no avail.

I want to use the modal form to add a new row with the inputted values to the jqGrid but I do not want it to post to the server upon Submit. I do want to eventually post to the server but only after the client user has performed additional editing (if needed) on the row(s) added from the modal form. I do not want any rows saved to the remote database until the client has performed some edits which in turn dynamically update other columns. Once a certain status of values are validated then a Save button is displayed and the Grid row(s) can be posted to the server. Unless this validated condition is met the row(s) are not to be submitted to the database. I have a number of jqGrids in use elsewhere in my app which do post the new row data of a submitted modal form but this grid I'm trying to accomplish something different with the client which doesn't immediately involve the server. I like the more intuitive interface of the modal form for the initial entry of values with the client user then editing inline the fields of the new row if needed which is what has necessitated my question: can I submit the form as a new row only without any posting action to the server occurring?

I saw in the jqGrid Wiki resource a comment made by a user who said if "clientArray" is the value entered for use the Grids modal form submission option "editurl: "clientArray" that the modal form would not spit the "No URL is set" message but it still does and a new row is not added to the grid. I've made the Grid datatype as a local "datatype: 'clientSide'" but get the same "No URL is set" error message. The script is pretty straightforward for the modal form which is invoked by a custom button as follows:

(The "footerrow, userDataOnFooter and altRows" options are included as part of the values updating in a summary footer which is related to editing performed upon the cells of the new row(s) being added through the modal form)

jQuery("#grid_test").jqGrid({
    url:'/grid_test_url.asp?id=' + vId,
    datatype: "clientSide",
    colNames: ['ID','Col 1', 'Col 2', 'Col 3','Col 4'],
    colModel: [

        {name:'id',index:'id',width:90,align:"center",editable:true,editoptions:{size:25}, formoptions: {...}, editrules: {...}},
        {name:'col1',index:'col1',width:130,align:"right",editable:true,editoptions:{size:25}, formoptions: {}, editrules: {}},
        {name:'col2',index:'col2',width:130,align:"right",editable:true,editoptions:{size: 25}, formoptions: {}, editrules: {}},
        {name:'col3',index:'col3',width:130,align:"right",editable: true,editoptions:{size:25}, formoptions: {}, editrules: {}},
        {name:'col4',index:'col4',width:130,align:"right",editable:true,editoptions:{ size: 25 }, formoptions: {}, editrules: {}}   

    ],
    rowNum:5,
    rowList:[5,10,20],
    pager: '#pgrid_test',
    toolbar: [true, "top"],
    editurl: '', //not sure what would go here to block attempted post by the Submit action of the modal form
    width: 500,
    sortname: 'id',
    viewrecords: true,
    sortorder: "asc",
    multiselect: true,
    cellEdit: true,
    caption: "Grid Test Add New Row",
    footerrow: true, 
    userDataOnFooter: true,
    altRows: true
})
jQuery("#grid_test").jqGrid('navGrid', '#pgrid_test', { add: false, edit: false, del: false })

//append custom button
$("#t_grid_test").append("<input type='button' class='add' value='Add New Row' style='height:20px; color:green; font-size:11px;' />");

$("input.add", "#t_grid_test").click(function () {
    jQuery("#grid_test").jqGrid('editGridRow', "new", {
        jqModal: true,
        savekey: [true, 13],
        navkeys: [true, 38, 40],
        bottominfo: "Fields marked with (*) are required. ",
        addCaption: 'New Row Values',
        width: 300,
        dataheight: 200,
        recreateForm: true,

      //checkOnUpdate: true,
      //checkOnSubmit: true,
      //reloadAfterSubmit: true,
        closeOnEscape: true,
        closeAfterAdd: true
        //clearAfterAdd: true
    })
});

I hope this is reasonably clear. It seems it should be rather simple to add a row using the modal form without it immediately posting to the server but I cannot work out the solution. And please bear with if I don't promptly click the icons for the proper credit given for answers but I will when I know what to click so please advise accordingly. :)
Many thanks in advance.
Jerry

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

三寸金莲 2024-11-07 13:20:20

当前版本的表单编辑不支持本地数据类型。尽管如此,我们还是可以用更长一点的代码来实现。我不久前创建了演示并发布了这里是在 jqGrid 中实现本地编辑支持的建议。目前还没有实现,但是你可以使用我的例子来实现你需要的。

我包含以下代码:

var lastSel, mydata = [
        {id:"1", invdate:"2007-10-01",name:"test",  note:"note",  amount:"200.00",tax:"10.00",closed:true, ship_via:"TN",total:"210.00"},
        {id:"2", invdate:"2007-10-02",name:"test2", note:"note2", amount:"300.00",tax:"20.00",closed:false,ship_via:"FE",total:"320.00"},
        {id:"3", invdate:"2007-09-01",name:"test3", note:"note3", amount:"400.00",tax:"30.00",closed:false,ship_via:"FE",total:"430.00"},
        {id:"4", invdate:"2007-10-04",name:"test4", note:"note4", amount:"200.00",tax:"10.00",closed:true ,ship_via:"TN",total:"210.00"},
        {id:"5", invdate:"2007-10-31",name:"test5", note:"note5", amount:"300.00",tax:"20.00",closed:false,ship_via:"FE",total:"320.00"},
        {id:"6", invdate:"2007-09-06",name:"test6", note:"note6", amount:"400.00",tax:"30.00",closed:false,ship_via:"FE",total:"430.00"},
        {id:"7", invdate:"2007-10-04",name:"test7", note:"note7", amount:"200.00",tax:"10.00",closed:true ,ship_via:"TN",total:"210.00"},
        {id:"8", invdate:"2007-10-03",name:"test8", note:"note8", amount:"300.00",tax:"20.00",closed:false,ship_via:"FE",total:"320.00"},
        {id:"9", invdate:"2007-09-01",name:"test9", note:"note9", amount:"400.00",tax:"30.00",closed:false,ship_via:"TN",total:"430.00"},
        {id:"10",invdate:"2007-09-08",name:"test10",note:"note10",amount:"500.00",tax:"30.00",closed:true ,ship_via:"TN",total:"530.00"},
        {id:"11",invdate:"2007-09-08",name:"test11",note:"note11",amount:"500.00",tax:"30.00",closed:false,ship_via:"FE",total:"530.00"},
        {id:"12",invdate:"2007-09-10",name:"test12",note:"note12",amount:"500.00",tax:"30.00",closed:false,ship_via:"FE",total:"530.00"}
    ],
    grid = $("#list"),
    onclickSubmitLocal = function(options,postdata) {
        var grid_p = grid[0].p,
            idname = grid_p.prmNames.id,
            grid_id = grid[0].id,
            id_in_postdata = grid_id+"_id",
            rowid = postdata[id_in_postdata],
            addMode = rowid === "_empty",
            oldValueOfSortColumn;

        // postdata has row id property with another name. we fix it:
        if (addMode) {
            // generate new id
            var new_id = grid_p.records + 1;
            while ($("#"+new_id).length !== 0) {
                new_id++;
            }
            postdata[idname] = String(new_id);
        } else if (typeof(postdata[idname]) === "undefined") {
            // set id property only if the property not exist
            postdata[idname] = rowid;
        }
        delete postdata[id_in_postdata];

        // prepare postdata for tree grid
        if(grid_p.treeGrid === true) {
            if(addMode) {
                var tr_par_id = grid_p.treeGridModel === 'adjacency' ? grid_p.treeReader.parent_id_field : 'parent_id';
                postdata[tr_par_id] = grid_p.selrow;
            }

            $.each(grid_p.treeReader, function (i){
                if(postdata.hasOwnProperty(this)) {
                    delete postdata[this];
                }
            });
        }

        // decode data if there encoded with autoencode
        if(grid_p.autoencode) {
            $.each(postdata,function(n,v){
                postdata[n] = $.jgrid.htmlDecode(v); // TODO: some columns could be skipped
            });
        }

        // save old value from the sorted column
        oldValueOfSortColumn = grid_p.sortname === "" ? undefined: grid.jqGrid('getCell',rowid,grid_p.sortname);

        // save the data in the grid
        if (grid_p.treeGrid === true) {
            if (addMode) {
                grid.jqGrid("addChildNode",rowid,grid_p.selrow,postdata);
            } else {
                grid.jqGrid("setTreeRow",rowid,postdata);
            }
        } else {
            if (addMode) {
                grid.jqGrid("addRowData",rowid,postdata,options.addedrow);
            } else {
                grid.jqGrid("setRowData",rowid,postdata);
            }
        }

        if ((addMode && options.closeAfterAdd) || (!addMode && options.closeAfterEdit)) {
            // close the edit/add dialog
            $.jgrid.hideModal("#editmod"+grid_id,
                              {gb:"#gbox_"+grid_id,jqm:options.jqModal,onClose:options.onClose});
        }

        if (postdata[grid_p.sortname] !== oldValueOfSortColumn) {
            // if the data are changed in the column by which are currently sorted
            // we need resort the grid
            setTimeout(function() {
                grid.trigger("reloadGrid", [{current:true}]);
            },100);
        }

        // !!! the most important step: skip ajax request to the server
        this.processing = true;
        return {};
    },
    editSettings = {
        //recreateForm:true,
        jqModal:false,
        reloadAfterSubmit:false,
        closeOnEscape:true,
        savekey: [true,13],
        closeAfterEdit:true,
        onclickSubmit:onclickSubmitLocal
    },
    addSettings = {
        //recreateForm:true,
        jqModal:false,
        reloadAfterSubmit:false,
        savekey: [true,13],
        closeOnEscape:true,
        closeAfterAdd:true,
        onclickSubmit:onclickSubmitLocal
    },
    delSettings = {
        // because I use "local" data I don't want to send the changes to the server
        // so I use "processing:true" setting and delete the row manually in onclickSubmit
        onclickSubmit: function(options) { //, rowid) {
            var grid_id = grid[0].id,
                grid_p = grid[0].p,
                newPage = grid_p.page,
                rowids = grid_p.multiselect? grid_p.selarrrow: [grid_p.selrow];

            // reset the value of processing option to true
            // because the value can be changed by jqGrid
            options.processing = true;

            // delete selected row/rows (multiselect:true)
            $.each(rowids, function () {
                grid.delRowData(this);
            });
            // delete the row
            //grid.delRowData(rowid);
            $.jgrid.hideModal("#delmod"+grid_id,
                              {gb:"#gbox_"+grid_id,jqm:options.jqModal,onClose:options.onClose});

            if (grid_p.lastpage > 1) {// on the multipage grid reload the grid
                if (grid_p.reccount === 0 && newPage === grid_p.lastpage) {
                    // if after deliting there are no rows on the current page
                    // which is the last page of the grid
                    newPage--; // go to the previous page
                }
                // reload grid to make the row from the next page visable.
                grid.trigger("reloadGrid", [{page:newPage}]);
            }

            return true;
        },
        processing:true
    },
    initDateEdit = function(elem) {
        setTimeout(function() {
            $(elem).datepicker({
                dateFormat: 'dd-M-yy',
                autoSize: true,
                showOn: 'button', // it dosn't work in searching dialog
                changeYear: true,
                changeMonth: true,
                showButtonPanel: true,
                showWeek: true
            });
            //$(elem).focus();
     },100);
    },
    initDateSearch = function(elem) {
        setTimeout(function() {
            $(elem).datepicker({
                dateFormat: 'dd-M-yy',
                autoSize: true,
                //showOn: 'button', // it dosn't work in searching dialog
                changeYear: true,
                changeMonth: true,
                showButtonPanel: true,
                showWeek: true
            });
            //$(elem).focus();
     },100);
    };

grid.jqGrid({
    datatype:'local',
    data: mydata,
    colNames:['Inv No','Date','Client','Amount','Tax','Total','Closed','Shipped via','Notes'],
    colModel:[
        {name:'id',index:'id',width:70,align:'center',sorttype: 'int',searchoptions:{sopt:['eq','ne']}},
        {name:'invdate',index:'invdate',width:80, align:'center', sorttype:'date',
         formatter:'date', formatoptions: {newformat:'d-M-Y'}, editable:true, datefmt: 'd-M-Y',
         editoptions: {dataInit:initDateEdit},
         searchoptions: {dataInit:initDateSearch}},
        {name:'name',index:'name',editable: true, width:70, editrules:{required:true}},
        {name:'amount',index:'amount',width:100, formatter:'number', editable: true, align:'right'},
        {name:'tax',index:'tax',width:70, formatter:'number', editable: true, align:'right'},
        {name:'total',index:'total',width:120, formatter:'number', editable: true, align:'right'},
        {name:'closed',index:'closed',width:110,align:'center',editable: true, formatter: 'checkbox',
         edittype:'checkbox',editoptions:{value:'Yes:No',defaultValue:'Yes'},
         stype: 'select', searchoptions: { sopt:['eq','ne'], value:':All;true:Yes;false:No' }},
        {name:'ship_via',index:'ship_via',width:120,align:'center',editable: true, formatter:'select',
         edittype:'select',editoptions:{value:'FE:FedEx;TN:TNT;IN:Intim', defaultValue:'Intime'},
         stype:'select', searchoptions:{value:':All;FE:FedEx;TN:TNT;IN:Intim'}},
        {name:'note',index:'note',width:100,sortable:false,editable:true,edittype:'textarea'}
    ],
    rowNum:10,
    rowList:[5,10,20],
    pager: '#pager',
    gridview:true,
    rownumbers:true,
    autoencode:true,
    ignoreCase:true,
    sortname: 'invdate',
    viewrecords: true,
    sortorder: 'desc',
    caption:'How to implement local form editing',
    height: '100%',
    editurl: 'clientArray',
    ondblClickRow: function(rowid, ri, ci) {
        var p = grid[0].p;
        if (p.selrow !== rowid) {
            // prevent the row from be unselected on double-click
            // the implementation is for "multiselect:false" which we use,
            // but one can easy modify the code for "multiselect:true"
            grid.jqGrid('setSelection', rowid);
        }
        grid.jqGrid('editGridRow', rowid, editSettings);
    },
    onSelectRow: function(id) {
        if (id && id !== lastSel) {
            // cancel editing of the previous selected row if it was in editing state.
            // jqGrid hold intern savedRow array inside of jqGrid object,
            // so it is safe to call restoreRow method with any id parameter
            // if jqGrid not in editing state
            if (typeof lastSel !== "undefined") {
                grid.jqGrid('restoreRow',lastSel);
            }
            lastSel = id;
        }
    }
}).jqGrid('navGrid','#pager',{},editSettings,addSettings,delSettings,
          {multipleSearch:true,overlay:false,
           onClose:function(form){
               // if we close the search dialog during the datapicker are opened
               // the datepicker will stay opened. To fix this we have to hide
               // the div used by datepicker
               $("div#ui-datepicker-div.ui-datepicker").hide();
           }});

更新:代码更改为与我在 答案中发布的 jqGrid 4.4.1 一起使用

更新2答案提供4.5.4的更新。

更新3:新的4.7版本的jqGrid现在支持本地数据的表单编辑。使用新版本的相应演示位于此处。我只需添加 formatter: "date" 的新 reformatAfterEdit: true 选项。 另一个演示使用jqGrid 4.6。

The current version of the form editing don't support local datatype. Nevertheless one can do implement if with a little more long code. I created the demo some time ago and posted here the suggestion to implement the local editing support in jqGrid. Till now it is not yet implemented, but you can use my example to implement what you need.

I include the code below:

var lastSel, mydata = [
        {id:"1", invdate:"2007-10-01",name:"test",  note:"note",  amount:"200.00",tax:"10.00",closed:true, ship_via:"TN",total:"210.00"},
        {id:"2", invdate:"2007-10-02",name:"test2", note:"note2", amount:"300.00",tax:"20.00",closed:false,ship_via:"FE",total:"320.00"},
        {id:"3", invdate:"2007-09-01",name:"test3", note:"note3", amount:"400.00",tax:"30.00",closed:false,ship_via:"FE",total:"430.00"},
        {id:"4", invdate:"2007-10-04",name:"test4", note:"note4", amount:"200.00",tax:"10.00",closed:true ,ship_via:"TN",total:"210.00"},
        {id:"5", invdate:"2007-10-31",name:"test5", note:"note5", amount:"300.00",tax:"20.00",closed:false,ship_via:"FE",total:"320.00"},
        {id:"6", invdate:"2007-09-06",name:"test6", note:"note6", amount:"400.00",tax:"30.00",closed:false,ship_via:"FE",total:"430.00"},
        {id:"7", invdate:"2007-10-04",name:"test7", note:"note7", amount:"200.00",tax:"10.00",closed:true ,ship_via:"TN",total:"210.00"},
        {id:"8", invdate:"2007-10-03",name:"test8", note:"note8", amount:"300.00",tax:"20.00",closed:false,ship_via:"FE",total:"320.00"},
        {id:"9", invdate:"2007-09-01",name:"test9", note:"note9", amount:"400.00",tax:"30.00",closed:false,ship_via:"TN",total:"430.00"},
        {id:"10",invdate:"2007-09-08",name:"test10",note:"note10",amount:"500.00",tax:"30.00",closed:true ,ship_via:"TN",total:"530.00"},
        {id:"11",invdate:"2007-09-08",name:"test11",note:"note11",amount:"500.00",tax:"30.00",closed:false,ship_via:"FE",total:"530.00"},
        {id:"12",invdate:"2007-09-10",name:"test12",note:"note12",amount:"500.00",tax:"30.00",closed:false,ship_via:"FE",total:"530.00"}
    ],
    grid = $("#list"),
    onclickSubmitLocal = function(options,postdata) {
        var grid_p = grid[0].p,
            idname = grid_p.prmNames.id,
            grid_id = grid[0].id,
            id_in_postdata = grid_id+"_id",
            rowid = postdata[id_in_postdata],
            addMode = rowid === "_empty",
            oldValueOfSortColumn;

        // postdata has row id property with another name. we fix it:
        if (addMode) {
            // generate new id
            var new_id = grid_p.records + 1;
            while ($("#"+new_id).length !== 0) {
                new_id++;
            }
            postdata[idname] = String(new_id);
        } else if (typeof(postdata[idname]) === "undefined") {
            // set id property only if the property not exist
            postdata[idname] = rowid;
        }
        delete postdata[id_in_postdata];

        // prepare postdata for tree grid
        if(grid_p.treeGrid === true) {
            if(addMode) {
                var tr_par_id = grid_p.treeGridModel === 'adjacency' ? grid_p.treeReader.parent_id_field : 'parent_id';
                postdata[tr_par_id] = grid_p.selrow;
            }

            $.each(grid_p.treeReader, function (i){
                if(postdata.hasOwnProperty(this)) {
                    delete postdata[this];
                }
            });
        }

        // decode data if there encoded with autoencode
        if(grid_p.autoencode) {
            $.each(postdata,function(n,v){
                postdata[n] = $.jgrid.htmlDecode(v); // TODO: some columns could be skipped
            });
        }

        // save old value from the sorted column
        oldValueOfSortColumn = grid_p.sortname === "" ? undefined: grid.jqGrid('getCell',rowid,grid_p.sortname);

        // save the data in the grid
        if (grid_p.treeGrid === true) {
            if (addMode) {
                grid.jqGrid("addChildNode",rowid,grid_p.selrow,postdata);
            } else {
                grid.jqGrid("setTreeRow",rowid,postdata);
            }
        } else {
            if (addMode) {
                grid.jqGrid("addRowData",rowid,postdata,options.addedrow);
            } else {
                grid.jqGrid("setRowData",rowid,postdata);
            }
        }

        if ((addMode && options.closeAfterAdd) || (!addMode && options.closeAfterEdit)) {
            // close the edit/add dialog
            $.jgrid.hideModal("#editmod"+grid_id,
                              {gb:"#gbox_"+grid_id,jqm:options.jqModal,onClose:options.onClose});
        }

        if (postdata[grid_p.sortname] !== oldValueOfSortColumn) {
            // if the data are changed in the column by which are currently sorted
            // we need resort the grid
            setTimeout(function() {
                grid.trigger("reloadGrid", [{current:true}]);
            },100);
        }

        // !!! the most important step: skip ajax request to the server
        this.processing = true;
        return {};
    },
    editSettings = {
        //recreateForm:true,
        jqModal:false,
        reloadAfterSubmit:false,
        closeOnEscape:true,
        savekey: [true,13],
        closeAfterEdit:true,
        onclickSubmit:onclickSubmitLocal
    },
    addSettings = {
        //recreateForm:true,
        jqModal:false,
        reloadAfterSubmit:false,
        savekey: [true,13],
        closeOnEscape:true,
        closeAfterAdd:true,
        onclickSubmit:onclickSubmitLocal
    },
    delSettings = {
        // because I use "local" data I don't want to send the changes to the server
        // so I use "processing:true" setting and delete the row manually in onclickSubmit
        onclickSubmit: function(options) { //, rowid) {
            var grid_id = grid[0].id,
                grid_p = grid[0].p,
                newPage = grid_p.page,
                rowids = grid_p.multiselect? grid_p.selarrrow: [grid_p.selrow];

            // reset the value of processing option to true
            // because the value can be changed by jqGrid
            options.processing = true;

            // delete selected row/rows (multiselect:true)
            $.each(rowids, function () {
                grid.delRowData(this);
            });
            // delete the row
            //grid.delRowData(rowid);
            $.jgrid.hideModal("#delmod"+grid_id,
                              {gb:"#gbox_"+grid_id,jqm:options.jqModal,onClose:options.onClose});

            if (grid_p.lastpage > 1) {// on the multipage grid reload the grid
                if (grid_p.reccount === 0 && newPage === grid_p.lastpage) {
                    // if after deliting there are no rows on the current page
                    // which is the last page of the grid
                    newPage--; // go to the previous page
                }
                // reload grid to make the row from the next page visable.
                grid.trigger("reloadGrid", [{page:newPage}]);
            }

            return true;
        },
        processing:true
    },
    initDateEdit = function(elem) {
        setTimeout(function() {
            $(elem).datepicker({
                dateFormat: 'dd-M-yy',
                autoSize: true,
                showOn: 'button', // it dosn't work in searching dialog
                changeYear: true,
                changeMonth: true,
                showButtonPanel: true,
                showWeek: true
            });
            //$(elem).focus();
     },100);
    },
    initDateSearch = function(elem) {
        setTimeout(function() {
            $(elem).datepicker({
                dateFormat: 'dd-M-yy',
                autoSize: true,
                //showOn: 'button', // it dosn't work in searching dialog
                changeYear: true,
                changeMonth: true,
                showButtonPanel: true,
                showWeek: true
            });
            //$(elem).focus();
     },100);
    };

grid.jqGrid({
    datatype:'local',
    data: mydata,
    colNames:['Inv No','Date','Client','Amount','Tax','Total','Closed','Shipped via','Notes'],
    colModel:[
        {name:'id',index:'id',width:70,align:'center',sorttype: 'int',searchoptions:{sopt:['eq','ne']}},
        {name:'invdate',index:'invdate',width:80, align:'center', sorttype:'date',
         formatter:'date', formatoptions: {newformat:'d-M-Y'}, editable:true, datefmt: 'd-M-Y',
         editoptions: {dataInit:initDateEdit},
         searchoptions: {dataInit:initDateSearch}},
        {name:'name',index:'name',editable: true, width:70, editrules:{required:true}},
        {name:'amount',index:'amount',width:100, formatter:'number', editable: true, align:'right'},
        {name:'tax',index:'tax',width:70, formatter:'number', editable: true, align:'right'},
        {name:'total',index:'total',width:120, formatter:'number', editable: true, align:'right'},
        {name:'closed',index:'closed',width:110,align:'center',editable: true, formatter: 'checkbox',
         edittype:'checkbox',editoptions:{value:'Yes:No',defaultValue:'Yes'},
         stype: 'select', searchoptions: { sopt:['eq','ne'], value:':All;true:Yes;false:No' }},
        {name:'ship_via',index:'ship_via',width:120,align:'center',editable: true, formatter:'select',
         edittype:'select',editoptions:{value:'FE:FedEx;TN:TNT;IN:Intim', defaultValue:'Intime'},
         stype:'select', searchoptions:{value:':All;FE:FedEx;TN:TNT;IN:Intim'}},
        {name:'note',index:'note',width:100,sortable:false,editable:true,edittype:'textarea'}
    ],
    rowNum:10,
    rowList:[5,10,20],
    pager: '#pager',
    gridview:true,
    rownumbers:true,
    autoencode:true,
    ignoreCase:true,
    sortname: 'invdate',
    viewrecords: true,
    sortorder: 'desc',
    caption:'How to implement local form editing',
    height: '100%',
    editurl: 'clientArray',
    ondblClickRow: function(rowid, ri, ci) {
        var p = grid[0].p;
        if (p.selrow !== rowid) {
            // prevent the row from be unselected on double-click
            // the implementation is for "multiselect:false" which we use,
            // but one can easy modify the code for "multiselect:true"
            grid.jqGrid('setSelection', rowid);
        }
        grid.jqGrid('editGridRow', rowid, editSettings);
    },
    onSelectRow: function(id) {
        if (id && id !== lastSel) {
            // cancel editing of the previous selected row if it was in editing state.
            // jqGrid hold intern savedRow array inside of jqGrid object,
            // so it is safe to call restoreRow method with any id parameter
            // if jqGrid not in editing state
            if (typeof lastSel !== "undefined") {
                grid.jqGrid('restoreRow',lastSel);
            }
            lastSel = id;
        }
    }
}).jqGrid('navGrid','#pager',{},editSettings,addSettings,delSettings,
          {multipleSearch:true,overlay:false,
           onClose:function(form){
               // if we close the search dialog during the datapicker are opened
               // the datepicker will stay opened. To fix this we have to hide
               // the div used by datepicker
               $("div#ui-datepicker-div.ui-datepicker").hide();
           }});

UPDATED: The code change to work with jqGrid 4.4.1 I posted in the answer.

UPDATED 2: The answer provide update for 4.5.4.

UPDATED 3: New 4.7 version of jqGrid supports now form editing of local data. The corresponding demo which uses the new version is here. I need just add new reformatAfterEdit: true option of formatter: "date". Another demo uses jqGrid 4.6.

幸福丶如此 2024-11-07 13:20:20

编辑
作为 4.3.2,网格的行为

4.3.1

onclickSubmitLocal = function(options,postdata) {
....
        // !!! the most important step: skip ajax request to the server
        this.processing = true;
        return {};

4.3.2

onclickSubmitLocal = function(options,postdata) {
....
        // !!! the most important step: skip ajax request to the server
        options.processing = true;
        return {};

发生了变化,否则网格返回 url 错误

EDIT
as 4.3.2 there is a change in behavior of the Grid

with 4.3.1

onclickSubmitLocal = function(options,postdata) {
....
        // !!! the most important step: skip ajax request to the server
        this.processing = true;
        return {};

with 4.3.2

onclickSubmitLocal = function(options,postdata) {
....
        // !!! the most important step: skip ajax request to the server
        options.processing = true;
        return {};

otherwise the grid return the url error

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文