java jquery mysql jqgrid free-jqgrid

java - $() datatable();



jqGrid-Identificación única para nueva fila (1)

Estoy tratando de asignar una identificación única a las nuevas filas que agrego a mi jqGrid. Utilizo libre jqGrid 4.11.0, un servicio de reposo de Java para el lado del servidor y MS SQL para las bases de datos.

inlineEditing: { ajaxSaveOptions: { contentType: "application/json" }, serializeSaveData: function (postData) { var idArray = grid.getCol(''id''); var count = 0; var k = 1; while(postData.id.search(''jqg'') != ''-1''){ for(var i =0 ; i<idArray.length;i++){ if(k == idArray[i]){ count++; } if(count == 0){ postData.id = k ; break; } } k++; } return JSON.stringify(postData); } }

Noté que la ID predeterminada dada por jqGrid es jqg + un número. ¿Alguna sugerencia sobre cómo puedo crear una identificación única que no esté actualmente en uso en ninguno de los registros de la base de datos? ¿Debo hacer esto desde el lado del servidor o puede hacerse en el código jqGrid?

En algún momento de la tarde, este código funcionaba y seguía dando id 7 a todas las filas nuevas [aunque debería haber seguido aumentando]. Después de algunos cambios [no recuerdo qué cambios], cada vez que hago clic en guardar para enviar la nueva fila al servidor, la página se congela y Chrome sugiere que debería matar el proceso.

Por favor, hágame saber qué y si debería agregar más información.

Edit1:

$(function () { var grid = $(''#grid''), checkboxEditOptionEvents = [ {type : ''click'', data: {''Yes'': ''Yes''}, fn: function (e, id) { var checkboxCol = grid.getCol(''sefDepartament''), ids = grid.jqGrid(''getDataIDs''), numberOfCheckedBoxes = [], k; for (k = 0; k < ids.length; k++) { if(checkboxCol[k] == ''Yes''){ numberOfCheckedBoxes.push(checkboxCol[k]); if (numberOfCheckedBoxes.length == 1){ alert(''Please deselect the other checked box first''); $(this).prop("checked",false); numberOfCheckedBoxes = 0; } } } }}]; var experienceFunction = function(cellvalue, options ,rowObject){ var joinYearVar = rowObject.joinYear, YY = joinYearVar.slice(0,4), MM = joinYearVar.slice(5,7), DD= joinYearVar.slice(8,11); return moment("/"" +YY+MM+DD+"/"" , "YYYYMMDD").fromNow(); }; var checkboxFormatFunc = function(cellvalue, options ,rowObject){ if(cellvalue == ''Yes''){ return ''Yes''; } return ''No''; }; var afterSaveFunction = function(id){ var prenumeVar = grid.getCell(id, ''prenume'').trim(), numeVar = grid.getCell(id,''nume'').trim(), usernameVar = numeVar +''.''+ prenumeVar, emailVar = usernameVar + ''@test.com''; usernameVar =usernameVar.replace(//s/g , '''').trim(); emailVar = emailVar.replace(//s/g , ''''); grid.setCell(id, ''username'', usernameVar); grid.setCell(id, ''email'', emailVar); }; var colModelSettings = [ {name:''id'', label:''id'',key: true,hidden: true, width:10,sorttype:''number'',editable: false}, {name:''nume'',label:''Nume'',width:90, align: ''center'',editable:true,searchoptions: {sopt: [''eq'',''bw'',''ew'',''cn'']}, editrules:{required:true}, editoptions: {defaultValue: '' ''},formatter: ''text''}, {name:''prenume'',label:''Prenume'',width:100,editable:true,searchoptions: {sopt: [''eq'',''bw'',''ew'',''cn'']},align: ''center'',editrules:{required:true},editoptions: {defaultValue: '' ''},formatter: ''text''}, {name:''username'',label:''Username'',searchoptions: {sopt: [''eq'',''bw'',''ew'',''cn'']},width:125,align: ''center'' }, {name:''email'',label:''Email'',width:135,searchoptions: {sopt: [''eq'',''bw'',''ew'',''cn'']},align: ''center''}, {name:''sefDepartament'',label:''Sef Departament'',width:90,editable:true,align: ''center'', stype:"select", searchoptions:{sopt: [''eq'',''ne''],value: "Yes:Yes;No:No"},formatter: checkboxFormatFunc,edittype:''checkbox'',editoptions: { dataEvents: checkboxEditOptionEvents,value:''Yes:No'', defaultValue: ''No'' }}, {name:''position'',label:''Position'',editable:true,stype: ''select'',formatter: ''select'',searchoptions: {sopt: [''eq'',''ne''],value: '' : ;position 1:position 1;position 2:position 2;position 3:position 3;position 4:position 4;position 5:position 5''}, align: ''center'',edittype:''select'',editoptions:{defaultvalue: ''P0: '',value: '' : ;position 1:position 1;position 2:position 2;position 3:position 3;position 4:position 4;position 5:position 5''},width: 75}, {name:''joinYear'',label:''Join Year'',formatter:''date'', formatoptions: {newformat:''d-m-Y''}, datefmt: ''dd-mm-yyyy'', editable:true,searchtype: ''datepicker'',align: ''center'',width: 70, searchoptions:{dateFormat:''dd-mm-yy'',dataInit: function (elem){ $(elem).datepicker({ showButtonPanel: true, dateFormat: ''yy-mm-dd''});},sopt: [''eq'',''ne'']}, editoptions:{size:20,defaultValue: '' '',dataInit: function (elem) { $(elem).datepicker({ showButtonPanel: true, dateFormat: ''dd-mm-yy''}); }}}, {name:''experience'', label:''Experience'', formatter: experienceFunction, searchoptions:{sopt: [''eq'',''bw'',''ew'',''cn'']}, editable:''hidden'', editoptions:{defaultValue: '' ''},align: ''center'',width: 60}, {name:''actiuni'',label: ''Actiuni'',formatter: ''actions'', formatoptions: {afterSave:afterSaveFunction},editable: false,sortable: false,search: false,width: 20 } ]; grid.jqGrid({ pager: ''#pager'', url: "/RestWithDatabaseConnection/rest/fetchData", editurl:''/RestWithDatabaseConnection/rest/update'', datatype: "json", height: 250, viewrecords: true, scrollOffset:0, sortorder: ''asc'', caption:''Employee List'' , autowidth: true, colModel: colModelSettings, beforeSelectRow : function(id){ var idsArray = grid.jqGrid(''getDataIDs''); var i; for(i=0;i<idsArray.length;i++){ if($(''#''+idsArray[i]).is(''[editable="1"]'') ){ grid.editRow(idsArray[i],true); return false; } } return true; }, inlineEditing: { ajaxSaveOptions: { contentType: "application/json" }, serializeSaveData: function (postData) { var idArray = grid.getCol(''id''); var count = 0; var k = 1; while(postData.id.search(''jqg'') != ''-1''){ for(var i =0 ; i<idArray.length;i++){ if(k == idArray[i]){ count++; } if(count == 0){ postData.id = k ; break; } } k++; } return JSON.stringify(postData); } } }); grid.jqGrid(''navGrid'', ''#pager'', {edit:false, add:false, delete:true, save:false, cancel:false, search:true, searchtext: ''Search'', refresh:true}, {},{},{ url: ''/RestWithDatabaseConnection/rest/delete'', mtype: ''DELETE'', reloadAfterSubmit: true, ajaxDelOptions: { contentType: "application/json", }, serializeDelData: function(postdata) { return JSON.stringify(postdata); }},{},{},{},{} ); grid.jqGrid(''inlineNav'',''#pager'', { edit:true, edittext: ''Edit'', save:true, savetext: ''Save'', add:true, cancel: true, canceltext: ''Cancel'', cancelicon: ''ui-icon-cancel'', addicon:''ui-icon-plus'', addtext: ''Add'', addedrow: ''last'', addParams: { position: ''last'', addRowParams: { aftersavefunc : afterSaveFunction, keys: true, } }, editParams:{ url: ''/RestWithDatabaseConnection/rest/update'', mtype : "POST", keys: true, aftersavefunc : afterSaveFunction, } })})

Edit2 - Respuesta del servidor a fetchData:

[{"id":"3","nume":"Aladin","prenume":"Zoro","username":"Aladin.Zoro","email":"[email protected]","sefDepartament":"Yes","position":"position 4","joinYear":"2015-11-08","experience":"2 months"}, {"id":"2","nume":"Harap","prenume":"Alb","username":"Harap.Alb","email":"[email protected]","sefDepartament":"No","position":"position 1","joinYear":"2016-01-03","experience":"9 days "}, {"id":"4","nume":"Don","prenume":"Homa","username":"Don.Homa","email":"[email protected]","sefDepartament":"No","position":"position 4","joinYear":"2015-09-06","experience":"4 months"}, {"id":"5","nume":"Dorel","prenume":"Gigel","username":"Dorel.Gigel","email":"[email protected]","sefDepartament":"No","position":"position 4","joinYear":"2016-01-10","experience":"2 days"}, {"id":"1","nume":"Ivan","prenume":"Stefan","username":"Ivan.Stefan","email":"[email protected]","sefDepartament":"No","position":"position 2","joinYear":"2016-01-10","experience":"2 days"}]


A continuación se encuentran algunos consejos para resolver su problema principal y mejorar el código JavaScript que ha publicado.

En primer lugar, la generación de nuevos rowids localmente es necesaria para el escenario de edición local. Uno debe generar los nuevos rowids en el servidor en caso de guardar los datos en el backend en la base de datos. La implementación típica consiste en tener PRIMARY KEY definida como int IDENTITY en cada tabla. Hace que los identificadores sean únicos y fijos. Eliminar una fila y crear la nueva nunca se interpretará como la edición de la fila anterior porque la nueva fila siempre obtendrá una nueva identificación, que nunca se utilizó antes (en la tabla).

Para tener la ventaja de los ID generados en el servidor, uno tiene dos opciones principales:

  1. volver a cargar la cuadrícula después de cada operación Agregar fila.
  2. extendiendo la comunicación con el servidor en la edición para que el servidor devuelva una nueva identificación, generada en la tabla de la base de datos, de vuelta a jqGrid. Se puede usar la aftersavefunc llamada aftersavefunc (para Agregar solo fila nueva) para actualizar rowid después de crear con éxito la fila en el servidor. Muchas implementaciones estándar de los servicios RESTful devuelven la Id. Inclusiva de datos de fila completa tanto en Agregar como Editar. Uno puede usar los datos dentro de la devolución de llamada aftersavefunc y usar algo como $("#" + rowid).attr("id", newRowid); para actualizar la nueva fila. Se guardó la identificación en algunas columnas adicionales (como si se usara una columna de id oculta), luego se debe usar el método setCell adicionalmente para actualizar la celda también.

La primera opción es la más simple y te recomendaría implementarla antes que nada. Solo si la recarga de la grilla no satisface a los usuarios, que añaden muchas filas una tras otra, entonces debe escribir un poco más de código e implementar la segunda situación.

inlineNav código actual usa inlineNav para inlineNav de Agregar y Editar, implementado usando la edición en línea, y el método navGrid para la operación Eliminar, implementado mediante la edición de formularios. La edición del formulario, inclusive Delete, usa la opción reloadAfterSubmit: true de forma predeterminada. Significa que la grilla se volverá a cargar desde el servidor (desde url: "/RestWithDatabaseConnection/rest/fetchData" ) después de eliminar cada fila. Puede resolver su problema principal reemplazando afterSaveFunction por lo siguiente:

var afterSaveFunction = function () { $(this).trigger("reloadGrid", [{current: true, fromServer: true}]); };

La opción current para mantener la selección actual después de volver a cargar y la opción fromServer: true solo tienen sentido en caso de que utilice la opción loadonce: true adicionalmente. Solo puede usar la reloadGridOptions: {fromServer: true} de navGrid para forzar la recarga de los datos del servidor al hacer clic en el botón Actualizar / Recargar de la barra de navegación. Si no tiene tantos datos que necesita mostrar en la cuadrícula (por ejemplo, menos de 1000 filas), entonces tal comportamiento sería recomendable.

Algunos consejos más comunes para mejorar tu código:

Puede considerar utilizar la height: "auto" lugar de la height: 250 y para administrar la altura máxima de la cuadrícula especificando el valor rowNum . La opción scrollOffset: 0 no será necesaria en el caso.

El formato de los datos devueltos por el servidor se ve de modo que no se implementan la paginación, clasificación y filtrado del lado del servidor . Debe usar loadonce: true y forceClientSorting: true opciones forceClientSorting: true . loadonce: true informa a jqGrid que guarda todos los datos devueltos desde el servidor localmente en el parámetro de data interno. En cualquier momento puede acceder a la matriz mediante el uso $(''#grid'').jqGrid("getGridParam", "data") . El valor de rowNum (el valor predeterminado es 20) se utilizará para la búsqueda local . El nombre de sortname y el orden de sortorder se usarán para la clasificación local . Y usará el cuadro de diálogo de búsqueda (agregado por navGrid ) o la barra de herramientas de filtro (agregado por filterToolbar ) para la búsqueda / filtrado local . Simplifica el código del servidor, mejora el rendimiento de la grilla desde el punto de vista del usuario y simplifica la interfaz entre el servidor y el cliente. Puede usar la interfaz RESTful clásica en el servidor sin ninguna extensión.

Otra observación: le recomendaría que elimine la columna de id oculto innecesaria ( name:''id'', label:''id'', key: true, hidden: true, ... ). La información sobre el rowid se guardará en el atributo id de las filas (elemento <tr> ) y no es necesario que contenga información duplicada en el elemento oculto <td> en cada fila.

Hay muchas otras partes de tu código, que podrían mejorarse. Por ejemplo, la operación DELETE que usa en el lado del servidor parece ser extraña. Utiliza mtype: ''DELETE'' , pero envía la identificación de la fila eliminada dentro del cuerpo de la solicitud al servidor en lugar de anexarla a la URL. Corresponde a los estándares, el HTTP DELETE no debe contener ningún cuerpo . Puede usar la opción formDeleting para especificar todas las opciones de Eliminar y puede definir el parámetro url como función:

formDeleting: { mtype: "DELETE", url: function (rowid) { return "/RestWithDatabaseConnection/rest/delete/" + rowid; }, ajaxDelOptions: { contentType: "application/json" }, serializeDelData: function () { return ""; } }

Necesita una causa modifique su código de servidor de /RestWithDatabaseConnection/rest/delete/ para usar el mismo protocolo de comunicación y para obtener la identificación de eliminada de la URL.

Puede usar el parámetro navOptions de free jqGrid para especificar las opciones de navGrid :

navOptions: { edit: false, add: false }

(texto de searchtext: ''Search'' y otras opciones que usted usa parecen tener valores predeterminados y yo los eliminé).

Para estar más cerca de los estándares REST, se puede usar la operación HTTP PUT para la edición de filas y HTTP POST para agregar nuevas filas. Debe implementar diferentes puntos de entrada para ambas operaciones en el back-end. /RestWithDatabaseConnection/rest/update ya y puedes implementar /RestWithDatabaseConnection/rest/create para agregar nuevas filas. Puede usar los siguientes cambios en la inlineEditing , por ejemplo, para implementar el escenario:

inlineNavOptions: { add: true, edit: true }, inlineEditing: { url: function (id, editOrAdd) { return "/RestWithDatabaseConnection/rest/" + (editOrAdd === "edit" ? "update" : "create"); }, mtype: function (editOrAdd) { return editOrAdd === "edit" ? "PUT" : "POST"; }, keys: true, serializeSaveData: function (postData) { return JSON.stringify(dataToSend); }, aftersavefunc: function () { $(this).trigger("reloadGrid", [{current: true, fromServer: true}]); }, addParams: { addRowParams: { position: "last", serializeSaveData: function (postData) { var dataToSend = $.extend({}, postData); // don''t send any id in case of creating new row // or to send `0`: delete dataToSend.id; // or dataToSend.id = 0; return JSON.stringify(dataToSend); } } } }