简体   繁体   English

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

[英]Adding new row to jqGrid using modal form on client only

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. 我想使用模式形式将带有输入值的新行添加到jqGrid,但是我不希望它在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. 我在应用程序的其他地方使用了许多jqGrids,它们确实发布了已提交的模态形式的新行数据,但是我正在尝试与不立即涉及服务器的客户端实现此网格不同的功能。 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: 我在jqGrid Wiki资源中看到一个用户的评论,该用户说如果“ clientArray”是使用网格模式表单提交选项“ editurl:“ clientArray”输入的值,则该模式表单不会吐出“未设置URL” ”消息,但是它仍然存在,并且没有将新行添加到网格。我已经将Grid数据类型设置为本地“数据类型:'clientSide'”,但是得到了相同的“未设置URL”错误消息。脚本是由自定义按钮调用的模态形式非常简单,如下所示:

(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) (“页脚,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
    })
});

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

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. 我前一段时间创建了演示,并在此处发布了在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 . 更新 :代码更改与jqGrid 4.4.1一起使用我在答案中发布

UPDATED 2 : The answer provide update for 4.5.4. 更新2答案提供了4.5.4的更新。

UPDATED 3 : New 4.7 version of jqGrid supports now form editing of local data. 更新3 :新的4.7版本的jqGrid现在支持对本地数据进行表单编辑。 The corresponding demo which uses the new version is here . 使用新版本的相应演示在这里 I need just add new reformatAfterEdit: true option of formatter: "date" . 我只需要添加新的reformatAfterEdit: true formatter: "date" reformatAfterEdit: true选项formatter: "date" Another demo uses jqGrid 4.6. 另一个演示使用jqGrid 4.6。

EDIT as 4.3.2 there is a change in behavior of the Grid 编辑为4.3.2 ,网格的行为发生了变化

with 4.3.1 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 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 否则,网格将返回url错误

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM