Agregar una nueva fila a jqGrid usando el formulario modal solo en el cliente

Parece que hay muchas soluciones que están muy cerca de abordar mi problema, pero de las docenas y docenas de preguntas que he formulado, ninguna parece tratar exactamente lo que trato de hacer. Aunque he visto casi la misma pregunta sin una respuesta. He intentado tantas combinaciones de opciones y funciones en vano.

Quiero usar el formulario modal para agregar una nueva fila con los valores ingresados ​​a jqGrid pero no quiero que se publique en el servidor al enviar. Deseo publicar eventualmente en el servidor, pero solo después de que el usuario del cliente haya realizado una edición adicional (si es necesario) en la (s) fila (s) agregada (s) desde el formulario modal. No quiero que se guarden filas en la base de datos remota hasta que el cliente haya realizado algunas modificaciones que, a su vez, actualicen dinámicamente otras columnas. Una vez que se valida un determinado estado de valores, se muestra un botón Guardar y las filas de la cuadrícula se pueden publicar en el servidor. A menos que se cumpla esta condición validada, la (s) fila (s) no se enviarán a la base de datos. Tengo una serie de jqGrids en uso en otra parte de mi aplicación que publican los datos de la nueva fila de un formulario modal enviado pero esta cuadrícula bash lograr algo diferente con el cliente que no involucra al servidor de inmediato. Me gusta la interfaz más intuitiva de la forma modal para la entrada inicial de valores con el usuario cliente y luego edito los campos de la nueva fila si es necesario, que es lo que ha requerido mi pregunta: ¿puedo enviar el formulario como una nueva fila solo sin cualquier acción de publicación para el servidor que ocurre?

Vi en el recurso jqGrid Wiki un comentario hecho por un usuario que dijo si “clientArray” es el valor ingresado para usar la opción de envío modal del formulario Grids “editurl:” clientArray “que el formulario modal no escupiría” No se establece el URL “mensaje pero todavía lo hace y una nueva fila no se agrega a la cuadrícula. He hecho el tipo de datos Grid como un” tipo de datos local: ‘clientSide’ “pero obtengo el mismo mensaje de error” No se estableció una URL “. bastante sencillo para el formulario modal invocado por un botón personalizado de la siguiente manera:

(Las opciones “footerrow, userDataOnFooter y altRows” se incluyen como parte de la actualización de valores en un pie de página de resumen que está relacionado con la edición realizada sobre las celdas de la (s) nueva (s) fila (s) añadidas a través del formulario 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 esto sea razonablemente claro. Parece que debería ser bastante simple agregar una fila usando el formulario modal sin que se publique inmediatamente en el servidor, pero no puedo encontrar la solución. Y tenga paciencia si no hago clic con prontitud en los íconos para obtener el crédito adecuado para las respuestas, pero lo haré cuando sepa en qué hacer clic, por lo que le aconsejo que lo haga. 🙂 Muchas gracias de antemano. alemán

La versión actual de la edición del formulario no admite el tipo de datos local. Sin embargo, uno puede implementar si con un código un poco más largo. Creé la demostración hace un tiempo y publiqué aquí la sugerencia para implementar el soporte de edición local en jqGrid. Hasta ahora, todavía no está implementado, pero puede usar mi ejemplo para implementar lo que necesita.

Incluyo el siguiente código:

 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 restreRow method with any id parameter // if jqGrid not in editing state if (typeof lastSel !== "undefined") { grid.jqGrid('restreRow',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(); }}); 

ACTUALIZADO : El cambio de código para trabajar con jqGrid 4.4.1 Publiqué en la respuesta .

ACTUALIZADO 2 : La respuesta proporciona actualización para 4.5.4.

ACTUALIZADO 3 : La nueva versión 4.7 de jqGrid ahora es compatible con la edición de datos locales. La demostración correspondiente que usa la nueva versión está aquí . Solo necesito agregar una nueva reformatAfterEdit: true opción reformatAfterEdit: true de formatter: "date" . Otra demostración usa jqGrid 4.6.

EDITAR como 4.3.2 hay un cambio en el comportamiento de la Grilla

con 4.3.1

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

con 4.3.2

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

de lo contrario, la cuadrícula devolverá el error de la url

    Intereting Posts