Aprendiendo Ext JS 3

Formato a la información de las celdas Más videos

Descripción del tema

En este tema vamos a ver la forma en que podemos modificar el contenido de las celdas utilizando un “interceptor” el cual se ejecutará antes de que el contenido sea “renderizado”, además veremos como cambiar el nombre de los parámetros que envía la barra de paginación al servidor. Lo que vamos a realizar es una tabla que contenga información sobre algunas razas de perros, esta tabla tendrá una imagen, nombre, descripción y algunos otros campos más, si lo deseas puedes probar el ejemplo en ejecución.
Tabla con formato

Tabla con formato personalizado en las celdas

Material de apoyo

Vamos a descargar el material de apoyo para que podamos seguir avanzando, después copia los archivos al servidor Web dentro de la carpeta “grids” en la que hemos estado trabajando. Recuerden que estamos trabajando con Ext JS 3.0.0, así que si no la tienes puedes ir a descargarla y copiar los archivos necesarios dentro de la carpeta “curso” en el servidor Web.

Información a mostrar

A continuación se muestra la información que el servidor nos regresará.
<?php
	header("Content-Type: text/plain"); 
	
	$offset = isset($_POST['offset'])?$_POST['offset']:0;
	$size = isset($_POST['size'])?$_POST['size']:5;
	
	$data = array(
		array('breed'=>'Beagle','origin'=>'Ancient Greece','agressive'=>false,'image'=>'images/beagle.jpg','description'=>'The Beagle is a breed of small to medium-sized dog. A member of the Hound Group, it is similar in appearance to the Foxhound but smaller, with shorter legs and longer, softer ears.'),
		array('breed'=>'German Shepherd','origin'=>'Germany','agressive'=>true,'image'=>'images/germanShep.jpg','description'=>'German Shepherds are a large-breed dog which generally are between 55 and 65 centimetres (22 and 26 in) at the withers and weigh between 22 and 40 kilograms (49 and 88 lb).'),
		array('breed'=>'Golden Retriever','origin'=>'United Kingdom','agressive'=>false,'image'=>'images/goldenRetriever.jpg','description'=>'The Golden Retriever is a breed of dog, historically developed as a gundog to retrieve shot waterfowl and upland game during hunting. As such they were bred to have a soft mouth to retrieve game undamaged and an instinctive love of water.'),
		array('breed'=>'Maltese','origin'=>'Central Mediterranean Area','agressive'=>false,'image'=>'images/maltese.jpg','description'=>'The Maltese is a small breed of dog in the toy group, known for its silky white hair, though many owners of pet Maltese give them a short "puppy cut" for ease of grooming.'),
		array('breed'=>'Rottweiler','origin'=>'Germany','agressive'=>false,'image'=>'images/rottweiler.jpg','description'=>'The Rottweiler, is a "medium to large size, stalwart dog" breed originating in Germany as a herding dog. It is a hardy and very intelligent breed.'),
		array('breed'=>'St. Bernard','origin'=>'Italy / Switzerland','agressive'=>false,'image'=>'images/stbernard.jpg','description'=>'The St. Bernard Dog is a very large breed of dog, a working dog from the Swiss Alps, originally bred for rescue. The breed has become famous through tales of alpine rescues, as well as for its enormous size.'),
		array('breed'=>'Whippet','origin'=>'England','agressive'=>false,'image'=>'images/whiteWhippet.jpg','description'=>'The Whippet is a breed of dog, of the sighthound family. They are active and playful and are physically similar to a small greyhound. Their popularity has led to the reuse of the Whippet name on a large number of things, from cars to cookies.'),
		array('breed'=>'Chihuahua','origin'=>'Mexico','agressive'=>true,'image'=>'images/chihuahua.jpg','description'=>'Breed standards for this dog do not generally specify a height, only a weight and a description of their overall proportions. As a result, height varies more than within many other breeds.')
	);
	
	$paging = array(
		'success'=>true,
		'total'=>count($data),
		'data'=> array_splice($data,$offset,$size)
	);
	
	
	echo json_encode($paging);
?>
En el código anterior la información está contenida en arreglos de PHP, para facilitar las cosas en este tutorial, normalmente esta información estaría en una base de datos o la podríamos obtener de un servicio Web (Web Service) o de cualquier otro lugar. Lo que esta haciendo el código es recibir dos parámetros, estos serán usados para paginar, luego imprime en formato JSON únicamente los registros que le solicitamos.

Definir el Namespace

El siguiente paso es definir el espacio de nombres que usaremos, no mencionaré el porqué de este paso porque ya lo hemos estudiado a detalle anteriormente.
Ext.ns('com.quizzpot.tutorial');

com.quizzpot.tutorial.GridFormatTutorial = {
	init: function(){		
		//aqui vamos a escribir el código inicial
	}
}

Ext.onReady(com.quizzpot.tutorial.GridFormatTutorial.init,com.quizzpot.tutorial.GridFormatTutorial);

Creación del Store

Ya vimos que el servidor nos regresa la información en formato JSON, por lo tanto vamos a utilizar el “JsonStore” por conveniencia.
var store = new Ext.data.JsonStore({
	url: 'gridformat.php',
	root: 'data',
	totalProperty: 'total',
	fields: ['breed','origin',{name:'agressive',type:'boolean'},'image','description']
});
store.load();
Ya debemos conocer el código anterior, pues no tiene nada de especial, simplemente define la URL donde se realizará la petición por medio de Ajax al servidor, los campos de los registros, el total que nos servirá para paginar la información y de donde sale la información de los registros (root).

Creación del paginador

Vamos a paginar los resultados, para eso creamos el componente “PagingToolbar” de la siguiente manera:
var pager = new Ext.PagingToolbar({
	store: store, // <--grid and PagingToolbar using same store
	displayInfo: true,
	displayMsg: '{0} - {1} of {2} Dog breeds',
	emptyMsg: 'No dog breeds to display',
	pageSize: 5
});
Ya hemos estudiado este componente en el tema anterior, por lo tanto debemos conocer el código anterior.

Crear el Grid y la Ventana contenedor

Ahora creamos el Grid y la ventana donde se mostrará de la siguiente manera:
var grid = new Ext.grid.GridPanel({
	store: store, //grid and PagingToolbar using same store
	columns: [
		new Ext.grid.RowNumberer(),
		{header:'Picture', dataIndex:'image',width:150,sortable: true},
		{header:'Breed name', dataIndex:'breed',width:140,sortable: true},
		{header:'Description', dataIndex:'description',width:180},
		{header:'Agressive', dataIndex:'agressive', width:60,sortable: true}
	],
	bbar: pager, // adding the pagingtoolbar to the grid
	border: false,
	stripeRows: true
});

var win = new Ext.Window({
	title: 'Grid example',
	layout: 'fit',
	width: 590,
	height:450,
	items: grid
});

win.show();
En primer lugar se crea el Grid, con las columnas necesarias y estas columnas se relacionan con las propiedades del Store mediante la propiedad “indexData”, le asignamos la barra de paginación y luego creamos la ventana que contiene al grid, ya estudiamos a detalle el código anterior en temas pasados es por eso que no me voy a detener a explicar más, si tienes dudas puedes consultar los tutoriales anteriores.
Tabla con formato

Grid sin formato

Como se puede ver en la imagen ya aparece la información en la tabla, pero no aparece la imagen ni el formato que queremos además el paginar no esta funcionando correctamente, ya que siempre nos regresa los mismos registros.

Cambiar los parámetros del paginador

Si regresamos a ver el código del servidor notamos que está recibiendo dos parámetros para paginar, uno de ellos es “offset” y “size”, si ya leíste el tema anterior sabrás que el componente “PagingToolbar” no envía esos parámetros, sino que envía “start” y “limit”, tenemos dos opciones, cambiar el código del servidor o de alguna manera cambiar el nombre de los parámetros a enviar por el paginador. Si por razones externas a nuestra voluntad no podemos cambiar el servidor, entonces para cambiar el nombre de estos parámetros lo hacemos en el store usando la propiedad “paramNames” de la siguiente manera:
paramNames: {
	start : 'offset',  // The parameter name which specifies the start row
	limit : 'size',  // The parameter name which specifies number of rows to return
	sort : 'sort',    // The parameter name which specifies the column to sort on
	dir : 'dir'       // The parameter name which specifies the sort direction
}
Entonces el store quedaría de la siguiente manera:
var store = new Ext.data.JsonStore({
	url: 'gridformat.php',
	root: 'data',
	totalProperty: 'total',
	paramNames: {
		start : 'offset',  // The parameter name which specifies the start row.
		limit : 'size',  // The parameter name which specifies number of rows to return.
		sort : 'sort',    // The parameter name which specifies the column to sort on.
		dir : 'dir'       // The parameter name which specifies the sort direction.
	},
	fields: ['breed','origin',{name:'agressive',type:'boolean'},'image','description']
});
store.load();
Esta propiedad (paramNames) recibe un objeto donde sobrescribimos el nombre de los parámetros a enviar al servidor, nótese que también debemos definir el “sort” y “dir” que en futuros temas hablaremos al respecto. Con esto es suficiente para que la paginación funcione adecuadamente.
Tabla con formato

Cambio de nombre a los parámetros de la paginación

Mostrar la imagen

Hasta ahora lo que tenemos en la columna de la imagen es la URL donde se encuentra la imagen a desplegar, lo que tenemos que hacer es utilizar la propiedad “renderer” del “ColumnModel” para modificar el contenido de la celda justo antes de que ésta sea renderizada.
var grid = new Ext.grid.GridPanel({
	store: store,
	columns: [
		new Ext.grid.RowNumberer(),
		{header:'Picture', dataIndex:'image',width:150,sortable: true, renderer: this.showImage}, // aqui definimos el “interceptor”
		{header:'Breed name', dataIndex:'breed',width:140,sortable: true },
		{header:'Description', dataIndex:'description',width:180 },
		{header:'Agressive', dataIndex:'agressive', width:60,sortable: true}
	],
	bbar: pager,
	border: false,
	stripeRows: true
});
Mediante la configuración “renderer: this.showImage” podemos definir una función, en este caso “showImage” que se ejecutará antes de que la celda sea “renderizada”, esta función debe regresar un String con el contenido que necesitamos desplegar en la celda, además también podemos generar el HTML.
com.quizzpot.tutorial.GridFormatTutorial = {
	init: function(){		
		//… código removido para major visualización …
	},
	//el interceptor
	showImage: function(value, metaData, record, rowIndex, colIndex, store){
		//retorna el contenido de la celda
		return 'recordgetbreed';
	}
}
Tabla con formato

Mostrar una imagen en la celda

La función que se configura en la propiedad “renderer” recibe seis parámetros, en este caso solo ocupamos solamente el “value” y el “record”, de acuerdo con la documentación los parámetros son los siguientes.
  • “value” (Object) : Es la información original que se imprimirá en la celda.
  • “metadata” (Object) : Un objeto en cual se pueden configurar los siguientes atributos:
    • “css” (String) : El nombre de una clase CSS para ser agregada al elemento TD de la celda.
    • “attr” (String) :Un atributo HTML definido como String para ser aplicado al DIV contenedor en la celda (ejemplo: 'style="color:red;"').
  • “record” (Ext.data.record) : El registro del Store de donde la información es extraída.
  • “rowIndex” (Number) : El índice de la fila
  • “colIndex” (Number) : El índice de la columna
  • “store” (Ext.data.Store) : El objeto store de donde el registro es extraído.

Dos campos en una misma celda

Lo que haremos ahora es poner dos campos del record dentro de una misma celda, además vamos a usar el parámetro “metaData” para ponerle un estilo y poder hacer que el texto pueda ocupar más de un solo renglón.
showBreed: function(value, metaData, record, rowIndex, colIndex, store){
	metaData.attr = 'style="white-space:normal"';
	return ''+value+' - '+record.get('origin');
}
Como puedes ver se imprime el valor original de la celda y le aplicamos una clase CSS que hace que el texto se ponga negrito, además estamos utilizando el “record” para acceder a otro campo, de esta manera podemos imprimir cualquier otro campo que necesitemos. Por último tenemos que definir la propiedad “renderer” a la columna “name” de la siguiente manera:
{header:'Breed name', dataIndex:'breed',width:140,sortable: true,renderer: this.showBreed},
Tabla con formato

Varios campos en una misma celda

Corregir la descripción

Si has notado, la descripción es mas larga que la celda y no se ve completa, lo que tenemos que hacer para que el texto se despliegue en renglones es modificar el CSS por medio del parámetro “metadata”, igual como lo hicimos en el paso anterior con el campo “breed”.
showDescription: function(value,metaData){
	metaData.attr = 'style="white-space:normal"';
	return value;
}
Con esto es suficiente para que la columna “Description” se pueda ver correctamente, recuerda asignarle esta función en la definición de la columna utilizando la propiedad “renderer”.
Tabla con formato

Asignando estilos a la celda

Cambiando el texto booleano

Por último vamos a cambiar el “true” y “false” de la columna “agressive” por algo más amigable.
showAgressive: function(value,metaData){
	metaData.attr = value?'style="color:#f00"':'style="color:#0a0"';
	return value?'Yes':'No';
}
El código anterior regresa “Yes” o “No” además en caso de ser “Yes” le asigna color rojo al texto y verde para cuando es un “No”.
Tabla con formato

Modificando los estilos y textos a deplegar en la celda

Conclusiones

Hemos visto como el Framework nos permite controlar completamente el contenido de una celda, podemos utilizar este método para realizar lo que sea necesario en nuestras aplicaciones. No olvides seguirnos en Twitter (@quizzpot) y si tienes alguna duda con respecto al tutorial o con respecto a cualquier otra cosa puedes inscribirte en los foros donde con gusto te ayudaremos entre todos los usuarios de la comunidad.

17Comentarios

  • F90425431ef71f833d1700477ec735c1?s=50&d=identicon pablo 11/07/2009

    gran tuto!!!!

    • C7a1f0f8439522fc03434a9573131e18?s=50&d=identicon Pepe 13/07/2009

      Muy bueno, te felicito. Gracias y un Saludo

      • F0995c352d67f35f411434564f3d4bd8?s=50&d=identicon Lord Tinchen 13/07/2009

        Excelente! Recuerdo haber pasado largo rato buscando información en su momento

        • F6ad0f154a1949981e05372583f0eebc?s=50&d=identicon Luis Alberto Cevallos Cavero 23/09/2009

          Hi it is a great tutorial but I need to add new rows from new grid to other grid that was checked please if you Know that explain me please I searching in the web but i don't find it. Thanks. Have a nice day.

          • F6ad0f154a1949981e05372583f0eebc?s=50&d=identicon Luis Alberto Cevallos Cavero 23/09/2009

            Excelente tutorial pero si sabes la manera de agregar filas de un grid en el cual he seleccionado con checks hacia otro te lo agradeceria mucho he buscado en muchos sitios y aun no doy. Gracias de antemano. Que tengas un excelente dia.

            • 7344c04fee0e5535e239b2a83623041a?s=50&d=identicon Crysfel 23/09/2009

              Hola Luis. Te recomiendo isncribirte en el foro (http://foro.quizzpot.com) donde podremos platicar mejor. saludos

              • 8730827ee593b14f1e92e852b68b4b44?s=50&d=identicon Ernesto 17/12/2009

                Hola a todos.. me está pasando que cuando descargo el codigo fuente del tutorial no me pincha el paginado, o sea no carga el resto de los elementos, pero si pincha en el ejemplo online.. alguna idea?? saludos para todos!

                • 7344c04fee0e5535e239b2a83623041a?s=50&d=identicon Crysfel 18/12/2009

                  necesitas poner el ejemplo dentro de un servidor web ya que realiza peticiones Ajax, podría ser eso.

                  • 11a10c29b87f9299072e65946d33f10b?s=50&d=identicon Jhon alexander 12/06/2010

                    Muchas gracias por todas las tutorias que ofrecen; me han servido de mucho . Sigan asi.................

                    • 64e9e1949edd3371ebeb04fc80976d8a?s=50&d=identicon Hector Rubio 05/10/2010

                      Saludos Cordiales, Creo que voy bien hasta el momento, he podido crear algunas rutinas y funcionan, sin embargo tengo un problemita: {header: "Descripción", width: 350, sortable: true, dataIndex: 'cldDescrip',renderer: this.MuestraDescrip}, MuestraDescrip: function(value,metaData){ metaData.attr = 'style="white-space:normal"'; return value;} Esto es parte del codigo; la tabla se muestra perfectamente, pero la funcion la ignora, no sale error, pero el texto no se adapta al campo, te enviare el codigo completo, Gracias

                      • F35fe51f91148baf8e9445a4ea2d5dca?s=50&d=identicon Hector I. Rubio A. 05/10/2010

                        Saludos Cordiales, Voy de nuevo; tengo un detalle y no encuentro donde esta el error Este archivo lo llame frmtablavacia.js y este es el codigo Ext.onReady(function() { // Creando el panel contenedor var tblPanel = new Ext.Panel({ height: 450, title: '(Tabla 1.1) Actividades Individuales de la Semana 1', collapsible: true, autoLoad: { url: 'frmtabla.htm', scripts: true }, renderTo: 'tblActividades', }); }) ************************************ Este archivo se llama actividad.htm: esto se muestra fuera del div cuando ejecuto ¿Por que? ********************** Y este archivo es frmtabla.htm: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Todo se ejecuta bien, pero manad un error el explorador y es este: Detalles de error de página web Mensaje: Acceso denegado. Línea: 7 Carácter: 20287 Código: 0 URI: file:///C:/Laboratorios/CursoCisel/extjs321/adapter/ext/ext-base.js ¿Donde esta el error?, ¿que estoy haciendo mal?. Si le cambio autoLoad por cualquier otra cosa funciona perfectamente, excepto por lo que esta en el div se muestra del lado de afuar de este y no dentro del div como quiero que se vea, ¿se puede o no mostrar contenido html como por ejemplo una tabla, sin tener que estar programandola? Gracias. Gracias

                        • F35fe51f91148baf8e9445a4ea2d5dca?s=50&d=identicon Hector I. Rubio A. 05/10/2010

                          Perdon por lo anterior, no se por que no se mostro --- Actividad.htm ---- Todo lo que coloque aqui se muestra fuera del div ¿Por que razon? ---- frmtabla.htm ----- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;

                          • F35fe51f91148baf8e9445a4ea2d5dca?s=50&d=identicon Hector I. Rubio A. 05/10/2010

                            Bendita sea, disculpa, te lo mando por correo

                            • 90c9ea99efc6a0372c8346b7ca88f9cc?s=50&d=identicon Hector 01/08/2012

                              Tengo un grid con dos columnas y una fila, en esta fila solo quiero visualizar una imagen en cada celda sin necesidad de obtener información de base de datos o de un array, es decir solo quiero las imágenes en esa celdas, ya que quiero utilizarlas como botones pero no me sale cuando uso el renderer no me muestra ninguna imagen. tendrás algún ejemplo de esto?

                              • Ab143384b818bdaed370de06f5d5869f?s=50&d=identicon reinier 05/01/2013

                                Hola muy interesante realmente este tutorial, solo que estoy iniciandome con la versión 4.1.1 y necesito mostrar todo el contenido de un campo cargado de la BD, pero no me funciona de esta forma showDescription: function(value,metaData){ metaData.attr = 'style="white-space:normal"'; return value; } Asignando por supuesto esta funcion al renderer de la columna. Agradeceria grandemente su ayuda.

                                • Fe40ad7911c0f56690889cb4bd1494d9?s=50&d=identicon Senpai 05/04/2014

                                  Estoy usando ExtJS 4, esta parte del codigo no me funciona: showDescription: function(value, metaData) { metaData.attr = 'style="white-space: normal"'; return value; }

                                Instructor del curso

                                Crysfel Villa

                                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