Aprendiendo Ext JS 3

Llenar formularios con información del servidor Más videos

Descripción del tema

En el tema de hoy veremos como llenar un formulario utilizando Ajax para realizar la petición al servidor solicitando la información mediante un identificador que mandaremos como parámetro. Ya vimos como llenar un formulario de Ext JS a través de un record, el día de hoy lo llenaremos sacando la información a través de una petición Ajax al servidor.

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.
Formulario cargado con Ajax

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.
Formulario cargado con Ajax

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 cargado con Ajax

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 con Ajax

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.

¿Olvidaste tu contraseña?

23Comentarios

  • Avatar-3 Robert 04/08/2009

    Muy bien explicado el tema, muchas gracias saludos

    • Avatar-7 dekpitado 05/08/2009

      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 :)....

      • Avatar-5 Crysfel 05/08/2009

        Te recomiendo inscribirte en el foro (http://foro.quizzpot.com) y formar parte de la comunidad ;)

        • Avatar-5 Héctor 29/08/2009

          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

          • Avatar-5 Jesus Manuel Olivas 16/09/2009

            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

            • Avatar-8 Yethael 09/12/2009

              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?

              • Avatar-3 Crysfel 09/12/2009

                Es lo mismo

                • Avatar-9 Alirio 26/02/2010

                  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

                  • Avatar-9 Crysfel 26/02/2010

                    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

                    • Avatar-8 Alirio 26/02/2010

                      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

                      • Avatar-9 Alirio 27/02/2010

                        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.

                        • Avatar-5 Crysfel 01/03/2010

                          haciendo un "load()" al formulario ;) saludos

                          • Avatar-2 Pedro 13/04/2010

                            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

                            • Avatar-4 oscar 27/05/2010

                              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

                              • Avatar-9 Crysfel 27/05/2010

                                Utiliza la propiedad "params" que recibe un objeto con los parámetros que deseas envíar. Saludos

                                • Avatar-7 David 12/11/2010

                                  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

                                  • Avatar-10 Warbandit 30/11/2010

                                    Este problema tambien me ocurre a mi, si tienes la solución pr favor Hazmela saber, gracias.

                                    • Avatar-4 Crysfel 04/02/2011

                                      Necesitas definir la configuración "hiddenName" ;)

                                      • Avatar-11 Ronals 09/06/2011

                                        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

                                        • Avatar-10 Maria Chavira 05/12/2014

                                          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

                                          • Avatar-2 Crysfel Villa 05/12/2014

                                            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

                                          • Avatar-7 Juan Díaz Pérez 31/07/2015

                                            Los artículos que he estado consultando son muy valisos

                                            • Avatar-6 Josue Seijas 26/08/2016

                                              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?

                                              Instructor del curso

                                              Crysfel3

                                              Autor: Crysfel Villa

                                              Es ingeniero de software con más de 7 años de experiencia en desarrollo web.

                                              Descarga Código Fuente Ver Demostración

                                              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.