2011-04-10 17 views
6

Parece que hay muchas soluciones que están muy cerca de abordar mi problema, pero de las docenas y docenas de preguntas que he vertido no parece abordar exactamente lo que hago. estoy tratando de hacer Aunque he visto casi la misma pregunta sin una respuesta. He intentado tantas combinaciones de opciones y funciones en vano.Añadiendo una nueva fila a jqGrid utilizando el formulario modal en el cliente solamente

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 intento 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 decía si "clientArray" es el valor ingresado para usar la opción de envío modal de Grids "editurl:" clientArray "que la forma modal no escupía" No se establece un "mensaje de URL" pero todavía lo hace y no se agrega una nueva fila a la cuadrícula. He hecho que el tipo de datos Grid sea un "tipo de datos:" clientSide '"local pero obtengo el mismo mensaje de error" No se estableció una URL " La secuencia de comandos es bastante sencilla 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 resumen que está relacionado con edición realizada sobre las celdas de la (s) nueva (s) fila (s) que se agregan 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 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 
    }) 
}); 

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. Jerry

Respuesta

14

La versión actual de la edición del formulario no es compatible con el tipo de datos local. Sin embargo, uno puede implementar si con un código un poco más largo. Creé the demo hace algún tiempo y publiqué here la sugerencia de 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.

que incluyen el código de abajo:

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

ACTUALIZADO: El cambio de código para trabajar con jqGrid 4.4.1 he publicado en the answer.

ACTUALIZADO 2: The answer proporcionan la actualización para 4.5.4.

ACTUALIZADO 3: 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 es here. Solo necesito agregar la nueva opción reformatAfterEdit: true de formatter: "date". Another demo usa jqGrid 4.6.

+0

Gracias usted @Oleg. –

+0

@Frank: ¡De nada! – Oleg

+0

@Oleg - Exactamente lo que necesitaba. Desafortunadamente, parece que ya no funciona con jqGrid 4.6 o 4.7. El formulario no se restablece y luego los errores en "Cliente requerido", incluso si hay datos en el formulario, – MSquared

1

EDITAR como 4.3.2 hay un cambio en el comportamiento de la cuadrícula

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 rejilla devolver el error url

Cuestiones relacionadas