Adicionando nova linha ao jqGrid usando o formulário modal somente no cliente

Parece haver muitas soluções que estão muito próximas de abordar o meu problema, mas das dezenas e dúzias de perguntas que eu coloquei, nenhuma delas parece abordar exatamente o que estou tentando fazer. Embora eu tenha visto quase a mesma pergunta feita sem uma resposta. Eu tentei tantas combinações de opções e funções sem sucesso.

Eu quero usar o formulário modal para adicionar uma nova linha com os valores introduzidos para o jqGrid, mas eu não quero postar no servidor após o envio. Eu quero, eventualmente, postar no servidor, mas somente após o usuário do cliente ter realizado edição adicional (se necessário) na (s) linha (s) adicionada (s) a partir do formulário modal. Não quero que nenhuma linha seja salva no database remoto até que o cliente tenha executado algumas edições que, por sua vez, atualizam dinamicamente outras colunas. Quando um determinado status de valores é validado, um botão Salvar é exibido e as linhas da Grade podem ser postadas no servidor. A menos que esta condição validada seja atendida, a (s) linha (s) não deve (m) ser enviada (s) ao database. Eu tenho um número de jqGrids em uso em outro lugar no meu aplicativo que postam os dados da nova linha de um formulário modal enviado, mas essa grade estou tentando realizar algo diferente com o cliente que não envolve imediatamente o servidor. Eu gosto da interface mais intuitiva do formulário modal para a input inicial de valores com o usuário do cliente, em seguida, editando inline os campos da nova linha, se necessário, que é o que exigiu minha pergunta: posso enviar o formulário como uma nova linha sem alguma ação de postagem para o servidor que está ocorrendo?

Eu vi no recurso Wiki do jqGrid um comentário feito por um usuário que disse se “clientArray” é o valor inserido para usar a opção de envio de formulário modal Grids “editurl:” clientArray “que o formulário modal não cuspia” Nenhum URL está definido msgstr “” “mas ainda faz e uma linha nova não é adicionada à grade. Eu fiz o tipo de dados de Grade como um” tipo de dados local: ‘clientSide’ “mas adquira o mesmo” Nenhum URL é fixo “mensagem de erro. bastante simples para o formulário modal que é invocado por um botão personalizado da seguinte forma:

(As opções “footerrow, userDataOnFooter e altRows” são incluídas como parte da atualização dos valores em um rodapé de sumário relacionado à edição realizada nas células da nova linha (s) sendo adicionada através do formulário modal)

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.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 }) }); 

Espero que isso seja razoavelmente claro. Parece que deve ser bastante simples adicionar uma linha usando o formulário modal sem que ele seja postado imediatamente no servidor, mas não posso resolver a solução. E, por favor, tenha paciência se eu não clicar prontamente nos icons para obter o devido crédito pelas respostas, mas irei quando souber o que clicar, então, por favor, informe de acordo. 🙂 Muito obrigado antecipadamente. Jerry

    A versão atual da edição do formulário não suporta tipos de dados locais. No entanto pode-se implementar se com um código um pouco mais longo. Eu criei a demo há algum tempo e postei aqui a sugestão para implementar o suporte de edição local no jqGrid. Até agora ainda não está implementado, mas você pode usar o meu exemplo para implementar o que você precisa.

    Eu incluo o código abaixo:

     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:'dM-Y'}, editable:true, datefmt: 'dM-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(); }}); 

    ATUALIZADO : O código muda para funcionar com o jqGrid 4.4.1 eu postei na resposta .

    ATUALIZADO 2 : A resposta fornece atualização para 4.5.4.

    ATUALIZADO 3 : A nova versão 4.7 do jqGrid suporta agora a edição de formulários de dados locais. A demonstração correspondente que usa a nova versão está aqui . Eu preciso apenas adicionar nova reformatAfterEdit: true opção do formatter: "date" . Outra demo usa o jqGrid 4.6.

    EDIT como 4.3.2 há uma mudança no comportamento do Grid

    com 4.3.1

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

    com 4.3.2

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

    caso contrário, a grade retornará o erro url