Llenar formularios con información del servidor Más videos
Descripción del tema
Material de Apoyo
Antes de continuar vamos a descargar el material de apoyo, el cual consta de tres archivos y una carpeta que contiene imágenes, debes copiar estos archivos al servidor Web en el que hemos estado trabajando, recuerda que esto es muy importante para que podamos utilizar Ajax.Demostración
En el ejercicio de hoy vamos a generar dinámicamente el “Top Ten” de las películas mas vistas en lo que va del 2009, luego al dar clic sobre alguna de estas aparecerá un formulario el cual se cargará haciendo una petición al servidor a través de Ajax, puedes ver la demostración de lo que tendremos cuando terminemos este tutorial.Ejemplo final
Información
Lo más importante en una aplicación es la información, en esta ocasión (y como siempre lo hemos hecho) la información está contenida en un arreglo en el servidor, pero recuerda que puede provenir de una base de datos como MySql, PostgreSQL, Oracle, de algún servicio Web (Web Service) o de cualquier otro lugar.<?php header("Content-Type: text/plain"); $all = isset($_GET['all']); $movie = isset($_POST['id'])?$_POST['id']:rand(0,9); $data = array( array('title'=>'G-Force','year'=>2009,'revenues'=>32.2,'comment'=>'Very good movie, it is an awesome movie','available'=>true,'img'=>'images/gforce.jpg'), array('title'=>'Harry Potter and the Half-Blood Prince','year'=>2009,'revenues'=>30,'comment'=>'Not to good, but it is ok','available'=>true,'img'=>'images/hpotter.jpg'), array('title'=>'The Ugly Truth','year'=>2009,'revenues'=>27,'comment'=>'Another comment to the movie','available'=>false,'img'=>'images/ugly.jpg'), array('title'=>'Orphan','year'=>2009,'revenues'=>12.8,'comment'=>'Testing the comment','available'=>'images/orphan.jpg','img'=>'images/orphan.jpg'), array('title'=>'Ice Age: Dawn of the Dinosaurs ','year'=>2009,'revenues'=>8.2,'comment'=>'Awesome movie, really good','available'=>true,'img'=>'images/ice.jpg'), array('title'=>'Transformers: Revenge of the Fallen','year'=>2009,'revenues'=>8,'comment'=>'Another test','available'=>false,'img'=>'images/transformers.jpg'), array('title'=>'The Hangover','year'=>2009,'revenues'=>6.46,'comment'=>'Testing','available'=>true,'img'=>'images/hangover.jpg'), array('title'=>'The Proposal','year'=>2009,'revenues'=>6.42,'comment'=>'Comment','available'=>true,'img'=>'images/proposal.jpg'), array('title'=>'Public Enemies','year'=>2009,'revenues'=>4.17,'comment'=>'One more comment','available'=>false,'img'=>'images/public.jpg'), array('title'=>'Brüno','year'=>2009,'revenues'=>2.72,'comment'=>'nothing to say','available'=>false,'img'=>'images/bruno.jpg') ); if($all){ $info = $data; }else{ $info = array( 'success'=>true, 'data'=> $data[$movie] ); } echo json_encode($info); ?>Lo más importante a mencionar en el código anterior es lo que se imprime dependiendo del parámetro “all”, ya que si es enviado en la petición imprimirá todo el arreglo de objetos en formato “json”, si no está presente se asume que se está solicitando específicamente un elemento.
Solicitar la información al servidor
Si en estos momentos ejecutas el HTML en tu explorador veras que solamente aparece el titulo, lo que tenemos que hacer es solicitar la información que vamos a desplegar utilizando Ajax, dentro del método “init” del objeto principal vamos a realizar esta petición de la siguiente manera:Ext.Ajax.request({ url: 'loadform.php', params: {all:true}, //solicitamos todos los registros method: 'GET', //utilizando el método GET scope: this, success: this.createTopTen //e indicamos la función que procesará la respuesta });Como hemos solicitado todos los registros obtenemos el siguiente resultado:
[{"title":"G-Force","year":2009,"revenues":32.2,"comment":"Very good movie, it is an awesome movie","available":true,"img":"images\/gforce.jpg"},{"title":"Harry Potter and the Half-Blood Prince","year":2009,"revenues":30,"comment":"Not to good, but it is ok","available":true,"img":"images\/hpotter.jpg"},{"title":"The Ugly Truth","year":2009,"revenues":27,"comment":"Another comment to the movie","available":false,"img":"images\/ugly.jpg"},{"title":"Orphan","year":2009,"revenues":12.8,"comment":"Testing the comment","available":"images\/orphan.jpg","img":"images\/orphan.jpg"},{"title":"Ice Age: Dawn of the Dinosaurs ","year":2009,"revenues":8.2,"comment":"Awesome movie, really good","available":true,"img":"images\/ice.jpg"},{"title":"Transformers: Revenge of the Fallen","year":2009,"revenues":8,"comment":"Another test","available":false,"img":"images\/transformers.jpg"},{"title":"The Hangover","year":2009,"revenues":6.46,"comment":"Testing","available":true,"img":"images\/hangover.jpg"},{"title":"The Proposal","year":2009,"revenues":6.42,"comment":"Comment","available":true,"img":"images\/proposal.jpg"},{"title":"Public Enemies","year":2009,"revenues":4.17,"comment":"One more comment","available":false,"img":"images\/public.jpg"},{"title":"Br\u00fcno","year":2009,"revenues":2.72,"comment":"nothing to say","available":false,"img":"images\/bruno.jpg"}]
Crear la lista del “Top Ten”
Con la información que recibimos podemos crear la lista del “Top Ten”, vamos a implementar la función “createTopTen” donde primeramente decodificamos el JSON para poder utilizarlo correctamente y luego mediante la clase “DomHelper” vamos a generar e insertar los nodos al DOM.var info = Ext.decode(response.responseText); //decodificamos el texto que recibimos Ext.each(info,function(movie){ //iteramos la información recibida Ext.DomHelper.append('content',{ //y creamos una imagen para cada elemento tag:'img', src:movie.img, alt:movie.title, title:movie.title, cls: 'movie' }); },this);Hemos estudiado previamente la clase “Ext.DomHelper”, por lo tanto debemos estar familiarizados con su uso, de no ser así te recomiendo repasar el tema donde estudiamos esta clase.
Creación de imagenes del Top Ten
Agregar “listeners” a las imágenes
Lo siguiente que necesitamos hacer es agregar un “listener” al evento “clic” de cada imagen que creamos, para que podamos mostrar el formulario con la información adecuada. Justo después de crear las imágenes vamos a seleccionar los nodos del DOM, las iteramos y le agregamos el evento a cada una.var items = Ext.DomQuery.select('div[id=content] > img'); Ext.each(items,function(el,i){ el = Ext.get(el); el.on('click',function(){ this.showDetail(i); //esta función será disparada cuando se dé clic a una imagen },this); },this);En el código anterior podemos ver que se disparará la función “showDetail(i);” cuando se de clic sobre alguna imagen, es importante mencionar que está recibiendo un parámetro “i” el cual indica el “id” de la imagen en la que se ha dado clic, esto nos servirá para solicitar la información correspondiente al servidor.
Crear el formulario
Es momento de crear el formulario dentro de la función “showDetail” de la siguiente manera:var form = new Ext.form.FormPanel({ url: 'loadform.php', //la URL de donde vamos a llenar el formulario border:false, labelWidth: 80, defaults: { xtype:'textfield', width: 150 }, items:[ {fieldLabel:'Title',name:'title'}, {xtype:'combo',fieldLabel:'Year',name:'year',triggerAction:'all',store:[2009,2008,2007,2006]}, {xtype:'numberfield',fieldLabel:'Revenues',name:'revenues'}, {xtype:'textarea',fieldLabel:'Comment',name:'comment'}, {xtype:'checkbox',fieldLabel:'',labelSeparator:'',boxLabel:'Available',name:'available'} ] });A estas alturas del curso debemos estar completamente familiarizados con el código anterior, lo único diferente y que es importante mencionar es la propiedad “url” en la cual se configura la “url” donde haremos la petición Ajax para llenar el formulario, además es importante notar que usamos la propiedad “name” en los campos del formulario. Lo siguiente que debemos hacer es crear la ventana que contendrá el formulario anterior.
var win = new Ext.Window({ title: 'Loading data into a form', bodyStyle: 'padding:10px;background-color:#fff;', width:300, height:270, items:[form], buttons: [{text:'Save'},{text:'Cancel'}] }); win.show();Si en este momento damos clic sobre cualquier imagen veremos algo semejante a la siguiente imagen.
Formulario vacio
Solicitar la información al servidor
Ya creamos el formulario y aparece al momento de dar clic sobre cada imagen, lo siguiente que haremos es llenarlo con la información correspondiente a la imagen solicitada, esto es muy sencillo ya que simplemente invocamos el método “load” con los parámetros necesarios:form.getForm().load({params:{id:id}});Debemos recordar que el formato JSON que debe regresar el servidor con la información es el siguiente:
{ "success":true, "data":{"title":"The Proposal","year":2009,"revenues":6.42,"comment":"Comment","available":true,"img":"images\/proposal.jpg"} }Es de suma importancia regresar el parámetro “success” en “true” (si no ha sucedido ningún error) para que se llene correctamente el formulario, de lo contrario el componente asume que se ocasionó algún error en el servidor y no lo llenará.
Formulario cargado mediante Ajax
Conclusiones
Hoy aprendimos a llenar el formulario mediante una llamada Ajax al servidor, es muy importante que la respuesta contenga la propiedad “success:true” para que funcione correctamente, desde mi punto de vista (muy personal) no me agrada que el componente nos obligue a realizar esto, sería mejor utilizar algún estado http para detectar si se ha ocasionado un error, de esta manera podríamos desarrollar nuestras aplicaciones utilizando complemente “REST” (más adelante hablaré al respecto). Como siempre si tienen dudas o sugerencias pueden hacerla en los foros, además recuerden seguirnos en Twitter (@quizzpot) para estar al tanto de las actualizaciones o bien si utilizas algún lector de RSS inscríbete a las Feeds o a déjanos tu correo electrónico y te mandaremos las actualizaciones allí.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.
23Comentarios
Muy bien explicado el tema, muchas gracias saludos
Vientos hijo, muy buen ejemplo donde se hace uso de varias cosas que nos pueden servir a nosotros los novatones !!!!!! :), hace poco me encontre con este sitio y me di cuenta de que tienes muy buenos articulos, asi que me van a estar viendo mas seguido por estos rumbos :)....
Te recomiendo inscribirte en el foro (http://foro.quizzpot.com) y formar parte de la comunidad ;)
Hola, muy bueno como siempre tu tutorial. me surge una duda. los campos del form deben tener el mismo nombre en la propiedad name que los campos que devuelve el json no? como lo hago para cargar directamente el form sin pasar por una funcion? imagino que es con form.getForm().load({params:{id:id}}); pero no logro saber como hacerlo. gracias
Si lo ejecutas desde un grid puedes hacer un funcion como esta y asi pasas el rec y no campo por campo y efectivamete los campos inputs tienen que tener el mismo nombre de la propiedad name de el store var rowSelectionModel = new Ext.grid.RowSelectionModel({ singleSelect: true, listeners: { rowselect: function(sm, row, rec) { Ext.getCmp("form-name").getForm().loadRecord(rec); } } }); y aplicarla al sm del gridPanel
Tengo una duda, si el combo fuese remoto, no hay algún problema al asignar el valor al combo mediante este método?, o se hace de otra forma?
Es lo mismo
buenas buenas, me he topado con este gran framework como lo es extjs, nunca he trabajado con este tipo de programacion, entiendo el procedimiento de tu ejemplo (el cual esta muy bueno), pero mi necesidad radica en que el formulario se llene directamente al cargar el archivo, no he logrado hacer, sera que me pueden dar una mano con esto?... Gracias
Hola Alirio. En el tutorial se explica como cargar el formularios, solamente tienes que poner la siguiente línea inmediatamente después de que has creado el formulario: form.getForm().load(); Saludos
Gracias Crysfel por tu respuesta tan rapida, pero me explico un poco mas detallado, tu luego que haces la consulta al servidor para obtener los datos, creas una imagen por cada registro encontrado, yo lo que necesito es crear un formulario para el registro que voy a conseguir en la base de datos, ya que lo que estoy haciendo es el modulo de edicion de datos del usuario... y pues se me ha hecho dificil adaptar tu ejemplo a mi necesidad... Muchisimas gracias por tu ayuda
mi duda es basicamente la misma que la del amigo Héctor, como se hace para sin tener que pasar por un grid llenar cargar los datos dentro del formulario.
haciendo un "load()" al formulario ;) saludos
Hola, necesito una ayuda con los datos tipo fecha....Siguiendo el mismo ejemplo que publicas, al agregar un campo tipo fecha, la cadena JSON es algo asi: {success:true, data:{"datfechfiltro":{"date":22,"day":4,"month":9,"time":1256187600000,"year":109}, El dato fecha es retornado como un objeto con propiedades: date, day, month, time Todos los demas datos cargan en el formulario, pero la fecha no. He puesto el mismo nombre del datefield (datfechfiltro) pero no carga el dato de la fecha. Probe de esta manera: {xtype: 'datefield',fieldLabel: 'FECHA INGRESO', name: 'datfechfiltro', id:'datfechfiltro', width: 100, renderer: Ext.util.Format.dateRenderer('d/m/Y')} Por favor, he buscado solucion pero no logro hacerlo funcionar. (Estoy utilizando la lib. json-lib.jar) Gracias
al momento de enviar la peticion al servidor quisiera mandarle variables , estoy realizando un ejemplo similar pero quiero q los datos de los combox se llenen dependiendo a unas variables que le mando a la peticion
Utiliza la propiedad "params" que recibe un objeto con los parámetros que deseas envíar. Saludos
Hola, muy buenos los tutoriales, el unico problema que hasta ahora hemos tenido, es que al enviar el formulario que contiene Combo Box, envia los displayField y no los valueField, a que se debe esto??, desde ya muchas gracias, Saludos
Este problema tambien me ocurre a mi, si tienes la solución pr favor Hazmela saber, gracias.
Necesitas definir la configuración "hiddenName" ;)
Hola Crysfel, lo que pasa es que estoy creando el objeto JsonStore para llenar un DataView, pero no caraga cuando le doy store.load(); el la documentacion del sencha me dice que utilice el metodo loadData(); pero no se que parametros debo pasar Espero tu respuesta gracias
Crysfel tengo un formulario que contiene dos combos El segundo de ellos se llena vía ajax según lo que se seleccione en el primero, la pregunta es: cuando hago un form.load para llenar mi formulario solo el primer combo muestra el valor que quiero seleccionar y el segundo me muestra en el display field el valor que envió como json y que corresponde al valuefield; que puedo hacer para que al cargar el formulario seleccione un valor por default del primer combo y de esta manera se llene el récord del segundo combo porque creo que ese es el problema
Hola Maria. Ese problema te sucede porque el segundo combo depende del primero, entonces, cuando llenas la información el segundo combo no contiene nada en el store, lo que te recomiendo es que selecciones el valor del segundo combo manualmente, esto lo harías cuando el store del segundo combo se ha cargado con éxito, en ese momento es que debes asignarle el valor que quieres seleccionar. Suerte
Los artículos que he estado consultando son muy valisos
Al correr el ejemplo me da un error en esta linea var info = Ext.decode(response.responseText); Y la consola dice Uncaught ReferenceError: response is not defined Alguien puede indicarme cual es la razón por favor?