Guardar los cambios del Grid editable usando Ajax Más videos
Descripción del tema
Material de apoyo
Para comenzar es necesario descargar el material de apoyo que consta de un archivo HTML donde únicamente se importa el Framework y hay clases "CSS" definidas, también encontrarás un archivo “JS” donde he definido el “namespace” y además algunos métodos que implementaremos en este tutorial, viene también un archivo “PHP” el cual nos servirá para simular el guardado y actualizado de información y por último una carpeta “icons” que contiene unas imágenes que mostraremos en los botones.Demostración
He preparado una demostración de lo que haremos al término de este tutorial, te invito a que la pruebes por ti mismo.Demostración
Guardar la información en el servidor
Para hacer más sencillo este ejemplo no voy a guardar la información en una base de datos, pues he de suponer que sabes como hacerlo así que voy a utilizar las “sesiones” para simular que guardamos y actualizamos la información, el código para lograr esto es el siguiente:<?php header("Content-Type: text/plain"); session_start(); $add = $_POST['records']; if(!isset($_SESSION['data'])){ $data = array( //creates the initial data 'success'=>true, 'total'=>11, 'data'=>array( array('id'=>1,'name'=>'John doe','age'=>23,'country'=>'USA'), array('id'=>2,'name'=>'Taylor Swift','age'=>19,'country'=>'USA'), array('id'=>3,'name'=>'Carlos Mena','age'=>22,'country'=>'México'), array('id'=>4,'name'=>'Christiano Ronaldo','age'=>24,'country'=>'Portugal'), array('id'=>5,'name'=>'Sasha Cohen','age'=>25,'country'=>'USA'), array('id'=>6,'name'=>'Christian Van Der Henst','age'=>27,'country'=>'Guatemala'), array('id'=>7,'name'=>'Collis Ta\'eed','age'=>31,'country'=>'USA') ) ); $_SESSION['data'] = $data; //load the data in sessions for the first time }else{ $data = $_SESSION['data']; //get the data if exist in session } if(isset($add)){ //if there are records to insert/update $records = json_decode(stripslashes($add)); //parse the string to PHP objects $ids = array(); foreach($records as $record){ if(isset($record->newRecordId)){ //records to insert $id = count($data['data']); $info = array( 'id'=> id, 'name'=> $record->name, 'age'=> $record->age, 'country'=> $record->country ); array_push($data['data'],$info); //add the new record to session array_push($ids,array('oldId'=>$record->newRecordId,'id'=>$id));//new id }else{ //records to update foreach($data['data'] as $key=>$r){ //search the record to update if($r['id'] == $record->id){ $data['data'][$key]['name'] = $record->name; //update the properties $data['data'][$key]['age'] = $record->age; $data['data'][$key]['country'] = $record->country; break; } } } } //print the success message echo json_encode(array( 'success'=>true, 'data'=>$ids )); }else{ //print all records in session echo json_encode($data); } ?>He comentado los puntos más importantes en el código, recuerda que es solo un ejemplo, en el mundo real deberías guardar la información en una base de datos o enviarlas a un WebService, etc. cuando implementes tu “controller” debes tener en cuenta que éste debe hacer dos cosas (por ahora).
- Si recibe registros (mediante el parámetro “post” llamado “records”) debe insertarlos o actualizarlos, esto depende de la variable “newRecordId” ya que si existe nos indica que es un registro nuevo y tiene que insertarse de lo contrario es un registro existente y tiene que actualizarse.
- Si no recibe registros solamente debe desplegar los registros que existen.
Creación del Grid editable
En este momento vamos a crear el Grid editable con los campos que definimos en el código anterior; escribiremos en el método “init” el siguiente código:init: function(){ //main code //creates the store for the grid var store = new Ext.data.JsonStore({ url: 'editorgrid-ajax.php', root: 'data', id:'id', fields: ['name','age','country'] }); //load the data store.load(); //creates the texfield to edit the data var textField = new Ext.form.TextField(); var numberField = new Ext.form.NumberField({allowBlank:false}); //creates the editor grid this.grid = new Ext.grid.EditorGridPanel({ store: store, columns: [ new Ext.grid.RowNumberer(), {header:'Name', dataIndex:'name',sortable: true,width:145,editor:textField}, {header:'Age', dataIndex:'age',sortable: true, editor:numberField}, {header:'Country', dataIndex:'country',sortable: true, editor:textField} ], border: false, stripeRows: true }); //creates a window to hold the grid var win = new Ext.Window({ title: 'Editor Grid example', layout: 'fit', width: 410, height:350, items: this.grid }); //show the window and the grid win.show(); },No me detendré a explicar el código anterior pues ya lo hice en los tutoriales anteriores, así que si no tienes idea de lo que pasó, te recomiendo comenzar con los tutoriales pasados. Hasta ahora deberíamos ver en pantalla algo como la siguiente imagen:
Grid editable
Guardar los registros modificados
Ahora si viene la parte interesante de este tutorial, pero primero necesitamos crear un botón para que al ser presionado por el usuario enviemos la información al servidor mediante Ajax, también vamos a crear un “ToolBar” donde estarán los botones que usaremos.var win = new Ext.Window({ title: 'Editor Grid example', tbar:{ defaults:{scope:this}, items:[ {text:'Save changes',iconCls:'save-icon',handler:this.save} ] }, layout: 'fit', width: 410, height:350, items: this.grid });
Toobar en la ventana contenedora
//save changes in the grid var modified = this.grid.getStore().getModifiedRecords();//step 1 if(!Ext.isEmpty(modified)){ var recordsToSend = []; Ext.each(modified, function(record) { //step 2 recordsToSend.push(Ext.apply({id:record.id},record.data)); }); this.grid.el.mask('Saving…', 'x-mask-loading'); //step 3 this.grid.stopEditing(); recordsToSend = Ext.encode(recordsToSend); //step 4 Ext.Ajax.request({ // step 5 url : 'editorgrid-ajax.php', params :{records : recordsToSend}, scope:this, success : function(response) { //step 6 this.grid.el.unmask(); this.grid.getStore().commitChanges(); } }); }En el paso 1 se recogen los registros que han sido modificados, esto nos regresa un arreglo con cada “record” que se modificó, luego verificamos que no este vacío. En el paso 2 iteramos el arreglo de registros modificados y vamos agregándolos a un arreglo que se llama “recordsToSend” en formato JSON, además incluimos el “id” ya que éste no se encuentra con el resto de la información. En el paso 3 le ponemos una máscara al Grid con el mensaje de “Saving…” y le agregamos la clase CSS “x-mask-loading” la cual muestra una animación que denota que se esta procesando algo. Mediante el método “stopEditing” nos aseguramos que el usuario no este editando ningún otro campo. En el paso 4 transformamos el “Array” a “String” para ser enviado al servidor en formato JSON. En el paso 5 realizamos la petición al servidor por medio de Ajax, definimos la “url” que invocaremos así como la información que se enviará en el parámetro “records”, recuerda que cuando enviamos información utilizando la propiedad “params” la petición se realiza por el método “post” por defecto. En el paso 6 definimos una función que se ejecutará cuando el servidor responda, dentro de esta función quitamos la máscara que cubría el Grid y hacemos un “commit” de los cambios ocurridos en el Grid, al hacer este “commit” los campos marcados como “sucios” (Dirty) dejarán de serlo.
Editando el contenido de las celdas
Enviando la información al servidor para ser guardada
La información ha sido guardada correctamente
Crear un registro nuevo
En la sección anterior logramos guardar los registros que fueron modificados por el usuario, ahora vamos a insertar nuevos registros en el Grid, para esto necesitamos crear un botón en la barra de herramientas que nos permita realizar lo antes mencionado.var win = new Ext.Window({ title: 'Editor Grid example', tbar:{ defaults:{scope:this}, items:[ {text:'Save changes',iconCls:'save-icon',handler:this.save}, {text:'Add Person',iconCls:'add-icon',handler:this.add} // add button ] }, layout: 'fit', width: 410, height:350, items: this.grid });Ahora necesitamos implementar el método “add” que está invocando el botón cuando es presionado.
//add a new row to the grid var position = this.grid.getStore().getCount(); var id = Ext.id(); var defaultData = { //step 1 newRecordId: id }; var Person = this.grid.getStore().recordType; //step 2 var person = new Person(defaultData,id); this.grid.stopEditing(); //step 3 this.grid.getStore().insert(position, person); // step 4 this.grid.startEditing(position, 1); //step 5El código anterior debe ser escrito dentro del método “add”. En el paso 1 se crea un objeto con la información por defecto, en este caso únicamente se está definiendo la propiedad “newRecordId” la cual es utilizada por el servidor para saber si el registro lo debe insertar o actualizar en la base de datos, el valor de esta propiedad ha sido generado mediante “Ext.id()” para tener un id único. El paso 2 es muy importante y es necesario porque cuando creamos el Store del grid nosotros no definimos ni el “Reader”, ni el “Record” directamente, esto lo hizo “Ext” automáticamente, por lo tanto no tenemos una referencia al “Record” generado, gracias a la propiedad “recordType” del “store” accedemos al “Record” que fue creado por el Framework dinámicamente, una vez que tenemos la referencia al componente “Record” creamos una instancia de éste con la información que generamos en el paso 1 y le asignamos su “id”. En el paso 3 solamente detenemos cualquier edición activa por parte del usuario. El paso 4 es el que hace la “magia”, ya que es aquí donde se inserta el nuevo “record” al store del Grid y automáticamente se reflejará la nueva fila vacía en el Grid, el primer parámetro que recibe este método es la posición donde queremos que se inserte, la posición la hemos calculado previamente contando el total de filas existentes esto nos da como resultado que la fila se inserte hasta el final del grid. En el paso 5 solamente hacemos que de la fila que acabamos de insertar en la columna número “1” aparezca una caja de texto (que definimos al crear el Grid) para editar el contenido de la celda, es importante mencionar que la columna “0” para este caso es la columna donde están los números, en caso de no tener esta columna podríamos comenzar a editar la columna “0”. Al actualizar nuestro explorador debería ver algo como la siguiente imagen en la pantalla:
Agregando una fila al Grid
Guardando él registro nuevo
Parámetros enviado al servidor por Ajax
//update the records with the correct ID's var info = Ext.decode(response.responseText); // step 1 Ext.each(info.data,function(obj){ var record = this.grid.getStore().getById(obj.oldId); //step 2 record.set('id',obj.id); //step 3 delete record.data.newRecordId; //step 4 },this);En el paso 1 se está decodificando la información que nos regresó el servidor en formato JSON para poder manipularla fácilmente. En el paso 2 se obtiene el “Record” utilizando el “id” que le fue asignado a la hora de crearlo. En el paso 3 se actualiza su “id” por el “id” asignado por el servidor en nuestra base de datos. El paso 4 es importante para eliminar la propiedad “newRecordId” que tiene el registro, de esta forma evitamos que se inserte nuevamente si solamente queremos actualizarlo.
Cancelar los cambios
Por defecto al editar el contenido de las celdas de un Grid éstas quedan en un estado de “Dirty”, en este estado nosotros podemos deshacer los cambios y regresar a la información original. Primero creamos el botón que nos permitirá realizar la acción pertinente.var win = new Ext.Window({ title: 'Editor Grid example', tbar:{ defaults:{scope:this}, items:[ {text:'Save changes',iconCls:'save-icon',handler:this.save}, {text:'Add Person',iconCls:'add-icon',handler:this.add}, {text:'Cancel changes',iconCls:'cancel-icon',handler:this.cancel} //cancel changes ] }, layout: 'fit', width: 410, height:350, items: this.grid });
Botón para cancelar los cambios
cancel: function(){ //cancel the changes in the grid this.grid.getStore().rejectChanges(); }Cuando invocamos el método “rejectChanges” del store, automáticamente regresan al estado original las celdas modificadas, esto es suficiente para deshacer los cambios ocurridos.
Conclusiones
En este tutorial aprendimos como guardar información a través de Ajax, también como insertar y actualizar los registros de un store y verlos reflejados en un Grid editable, en futuros tutoriales mostraré como hacerlo de una manera más sencilla utilizando las nuevas características de Ext 3. Si tienes alguna duda o sugerencia puedes hacerlo en los comentarios, recuerda que tenemos un foro donde la comunidad está creciendo y la participación es muy buena, te invito también a seguirnos en Twitter (@quizzpot) para estar al tanto de las actualizaciones del sitio.Te gustaría recibir más tutoriales como este en tu correo?
Este tutorial pertenece al curso Aprendiendo Ext JS 3, te recomiendo revises el resto de los tutoriales ya que están en secuencia de menor a mayor complejidad.
Si deseas recibir más tutoriales como este en tu correo te recomiendo registrarte al curso, si ya eres miembro solo identifícate y registrate al curso, si no eres miembro te puedes registrar gratuitamente!
Si no gustas registrarte en este momento no es necesario! Aún así puedes recibir los nuevos tutoriales en tu correo! Jamás te enviaremos Spam y puedes cancelar tu suscripción en cualquier momento.
Regístrate a este curso
Este tutorial pertenece al curso Aprendiendo Ext JS 3, revisa todos los tutoriales que tenemos en este mismo curso ya que están en secuencia y van de lo más sencillo a lo más complicado.
Tendrás acceso a descargar los videos, códigos y material adicional.
Podrás resolver los ejercicios incluidos en el curso así como los Quizzes.
Llevarás un registro de tu avance.
42Comentarios
Gracias.
La verdad es que son excelentes estos tutoriales. Gracias por el tiempo que te tomas al armarlos, en cuanto pueda voy a reconocer tu esfuerzo con algunos cafes. Gracias !!!
Realmente estoyinteresado en el Writter algún ejemplo para orientarme,he visto la documentacion de ext pero no termino de entenderlo
Hola amigos... excelente ejemplo pero como seria un ejemplo para guardar la informacion en la base de datos.. les agradesco mucho por su ayuda ya que recien estoy empezando a trabajar con esta gran libreria.. gracias
Para gusardar los cambios solamente necesitas tomar el parámetro en el servidor, convertir el JSON en objetos que puedas usar en el lenguaje de tu servidor y hacer un insert en la base de datos. saludos
puedes colocar el codigo para guardar en la base de dsatos por favor??
Buen dia señores, pienso que los tutoriales son muy completos, pienso que estan muy bien explicados y enfocados en ext-js. En mi opinion, y me disculpan, pedirle que nos ponga un ejemplo completo es desviarnos del tema, ya que esto tiene que ver con sql y el lenguaje que se utiliza, llamese java, php, phyton, etc. Seria mejor de investigar por otro lado y centrarnos en lo que nos interesa, ext-js. Gracias.
Hola, sip Excelente!!! Gracias !!!
crysfel, seria de gran ayuda u ejemplo de como hacer el update y el insert en el archivo php, favor tu ayuda
Eso es muy sencillo, y existen cientos de tutoriales al respecto ;) solamente usa las funciones que proporciona PHP para el manejo de base de datos, googlea un poco y encontrarás miles de ejemplos.
No seamos flojos y busqeumos un poco, como dice el sabio Crysfel, en googel teclea PHP + MySQL y saldran miles de links y en español. Una pregunta (espero no sea demasiado obvia). Crysfel: Como puede solo enviar al servidor los campos modificados y no toda la fila? es posible con lo que has mostrado hasta el momento?
Puedes hacerlo mediante "Ext.Ajax.request" enviando unicamente los campos que necesites, para ver si han sido modificados un registro revisa la propiedad "phantom" de cada record. saludos
Que buen tutorial, muchas gracias
Buen aporte, solo comentar que respeta la licencia de WP sobre el footer, se ve feo en un desarrollador quitar los creditos, suerte.
me funciona perfectamente excepto que al momento de presionar otro registro(add person), en los nuevos campos me arroja basura al momento de hacer doble click(editarlos). me podrias ayudar?
Registrate en el foro para platicar mejor sobre tu problema http://foro.quizzpot.com saludos
Hola Crysfel un gusto poder visitar nuevamente tu pagina de extJS, bueno tengo una pregunta amigo como puedo hacer un seleccionador de idiomas para mis aplicaciones echas en extjs, ejemplo que el usuario pueda elegir su propio idioma o elegir el idioma que el guste esto en un datagrip que tenga incorporado una opcion donde yo usuario pueda seleccionar el idioma que guste, esta aplicacion debera cambiar su idioma al idioma elegido, ya q en la libreria de estJS tenemos una carpeta q contiene muchos idiomas en la ruta src/locale/ en este lugar se encuentra varios idiomas bueno yo solo quiero q elegir tres idiomas español, ingles, portuges, para el ejemplo como lo puedo hacer esto una ayudita por favor como hacer este seleccionador de idiomas.
Muchas Gracias por compartir tus conocimientos, pero quiero solicitarte un favor, es posible que pongas un ejemplo de como seria en una base de datos?. Desde ya muchas Gracias..
Muchas gracias por el tutorial es de mucha ayuda pienso agregarle la opcion de eliminar un rejistro.
Y como manejas los errores??
hola Crysfel necesito hacer una grilla editable pero en XML intente convertir tu codigo JSON a XML pero tube demaciadas complicaciones, te agradeceria poder hacerlo en XML atte. SrCobranza.
Excelente tutorial....le estaré revisando ojala me sirva para lo que estoy haciendo se agradece :)
tengo una duda! como hago para recuperar todos los registros?, no solamente los modificados? # //save changes in the grid # var modified = this.grid.getStore().getModifiedRecords();//step 1 muchas gracias,, no he podido entender como recuperar Todos los datos de la grilla
oye tengo una duda. por que al mometo de actualizar un dato no lo hace y me inserta uno nuevo, pero la actualizacion no la hace
Tengo duda. por que al mometo de querer actualizar un dato me inserta otro?
Antes que nada queria felicitarte y agradecerte por los tutoriales realmente me han sido de gran utilidad. Estuve adaptando mi codigo para trabajar con base de datos (PostgreSQL), he logrado visualizar en el grid mis datos y hacer update en la base, pero estoy complicado con el INSERT. Desde ya muchas gracias por tu ayuda.
Hola cristel, muy bueno el tutorial, pero como seria para eliminar un registro?
Hola a todos. Es posible que EditorGridPanel, se pueda hacer un drag and drop como el GridPanel?? Saludos.
Saludos cordiales, Estoy agregando varios registros completos a la vez simulando una hoja de excel, pero al momento de grabar el metodo getModifiedRecords es vacio (A menos que vaya editando de uno en uno, cosa que no deseo hacer). Hay alguna forma de al momento de realizar el .getStore().insert(position, p); yo le de valor a alguna propiedad para que me devuelva estos registros con getModifiedRecords aún sin haberlos editado en el grid?. Muchas gracias y felicitaciones por el tutorial que me a salvado mas de una vez.
Uy que genialidad por dios!! muchas gracias por este tutorial!!
hola javier, recien comienzo con ext y tambien uso pgsql ... ando ahora en esto de los grids, podrias compatirme el codigo de tu insert ? ... muchas gracias
Hola muchas gracias por los tutoriales que has expuesto, yo soy programador en Delphi y recientemente salio un Wrapper llamado Extpascal que es el que yo uso, que traduce todo el ExtJs a codigo Pascal y la salida es un CGI, hasta aca todo bien, lo malo es que no es soportado por servidores externos, son contados los que les puedes meter mano en fin, he estado siguiendo tus tutoriales y googleando con el proposito de aprender ExtJs, ya he hecho grandes avances pero me falta aun, podrias poner este mismo tutorial pero agregando,editando los datos desde un formulario modal, quiero tener una idea de como implementar esto en mis pequeños ejercicios que me voy implementando, saludos y gracias.
Hey que le paso a Crysfel que no responde?, al menos pa saber que esta vivo, no!....?
Alguien me puede ayudar con otro contenedor para el grid que no sea un formulario para mantenerlo en una posicion estatica o q propiedad existe para que no permita mover la ventana donde aparece el grid
Hola, quisiera preguntarles, como hacen para borrar la cache, de forma que si modifico algo de html se refresque sin tener que cerrar todas las ventanas del explorador. gracias!
holaa estoy intentando que me guarde la info en una base de datos pero no funciona por me envia los datos como null ayuda
Genial código. Gracias. Ya he conseguido tanto que lea de la base de datos mysql y guarde la consulta en el array para ostrarlo, como que grabe en la BD tras cada cambio, el problema es que con cada cada cambio graba el array completo... Trato de hacer que solo me grabe el campo modificado, ya que si hay mucha info en la BD sería muy lento e ineficiente... Si alguien quiere el código, perfectamente funcional que me lo pida. info@mikelweb.net
enviamame el codigo para realizarlo con base de datos gracias de antemano
Muchasssssss gracias, tas durisimo en Ext. me sirvio de mucho.
esta pagina me sirvio de mucho, gracias Crysfel Nose si funcione este link, pero quiero hacer lo siguiente: tengo una grilla con 4 columnas, solo quiero hacer update a un solo campo, como lo puedo hacer?.
me olvide, decir que el dato actualizador viene de un combo que no esta en la grilla
hay algun ejemplo de un crud pero con formulario deje funcionando el ejemplo del crud con grid, pero me gustaria que al editar se abriera una ventana y no estubiera al costado como en el ejemplo que habia slds y gracias Nelson Stuardo