Aprendiendo Ext JS 3

Utilizando fechas y tiempo en un Grid Más videos

Descripción del tema

Desplegar una fecha o una hora en un grid es algo muy común, si no sabemos como utilizar correctamente este tipo de dato podemos meternos en problemas y puede darnos muchos dolores de cabeza. En este tema explicaré como podemos mostrar las fechas en diferentes formatos, además veremos como podemos ordenar correctamente ascendente o descendentemente las fechas contenidas en una tabla. El ejercicio que haremos es una simple “grilla” donde se mostrarán algunas fechas aleatorias en diferentes formatos, puedes ver el ejemplo del tutorial y probar su funcionalidad, recuerda que usaremos Ext JS 3.0.0.
Dates in grid

Ejercicio final

Material de apoyo

Antes de continuar adelante es necesario descargar el material de apoyo y copiar los archivos al servidor Web que instalamos al inicio de este curso.

Información a mostrar

La información que desplegaremos en el Grid se muestra a continuación:
<?php
	header("Content-Type: text/plain"); 
	
	$data = array(
		array('name'=>'John Doe','from'=>randomDate('m-d-Y'),'to'=> randomDate('j-M-Y'),'time'=>randomDate('h:i:s a'),'iso'=>randomDate('c'),'unix'=>randomDate('U')),
		array('name'=>'Crysfel','from'=>randomDate('m-d-Y'),'to'=> randomDate('j-M-Y'),'time'=>randomDate('h:i:s a'),'iso'=>randomDate('c'),'unix'=>randomDate('U')),
		array('name'=>'Sasha','from'=>randomDate('m-d-Y'),'to'=> randomDate('j-M-Y'),'time'=>randomDate('h:i:s a'),'iso'=>randomDate('c'),'unix'=>randomDate('U')),
		array('name'=>'Peter','from'=>randomDate('m-d-Y'),'to'=> randomDate('j-M-Y'),'time'=>randomDate('h:i:s a'),'iso'=>randomDate('c'),'unix'=>randomDate('U')),
		array('name'=>'Carl','from'=>randomDate('m-d-Y'),'to'=> randomDate('j-M-Y'),'time'=>randomDate('h:i:s a'),'iso'=>randomDate('c'),'unix'=>randomDate('U')),
		array('name'=>'Ronaldo','from'=>randomDate('m-d-Y'),'to'=> randomDate('j-M-Y'),'time'=>randomDate('h:i:s a'),'iso'=>randomDate('c'),'unix'=>randomDate('U')),
		array('name'=>'Jenny','from'=>randomDate('m-d-Y'),'to'=> randomDate('j-M-Y'),'time'=>randomDate('h:i:s a'),'iso'=>randomDate('c'),'unix'=>randomDate('U')),
		array('name'=>'Gina','from'=>randomDate('m-d-Y'),'to'=> randomDate('j-M-Y'),'time'=>randomDate('h:i:s a'),'iso'=>randomDate('c'),'unix'=>randomDate('U')),
		array('name'=>'Eddy','from'=>randomDate('m-d-Y'),'to'=> randomDate('j-M-Y'),'time'=>randomDate('h:i:s a'),'iso'=>randomDate('c'),'unix'=>randomDate('U'))
	);
	
	$response = array(
		'success'=>true,
		'total'=>count($data),
		'data'=> $data
	);
	
	
	echo json_encode($response);
	
	function randomDate($format){
		return date($format,rand(0,time()));
	}
?>

Como se pueden dar cuenta se están generando las fechas de manera aleatoria, así que no esperen ver las mismas fechas siempre, lo único que es constante es el nombre de las personas. También es importante notar que las fechas son generadas en diferentes formatos, puedes ver que también usamos el formato de “unix”, especificando los segundos transcurridos a partir del 1ro de enero de 1970.

Namespace

Una vez definida la información vamos a comenzar a trabajar del lado de cliente, por lo tanto necesitamos definir el espacio de nombre que usaremos para este tutorial.
Ext.ns('com.quizzpot.tutorial');

com.quizzpot.tutorial.DatesTutorial = {
	init: function(){		
		//el código va aqui
	}
}

Ext.onReady(com.quizzpot.tutorial.DatesTutorial.init,com.quizzpot.tutorial.DatesTutorial);
Ya sabemos el por qué de utilizar un namespace robusto, si no lo recuerdas te sugiero repasar el tema correspondiente.

Crear el Store y el Grid

Vamos a crear el Store capaz de procesar la información regresada por el servidor, la cual esta en formato JSON.
 
var store = new Ext.data.JsonStore({
	url: 'dates.php',
	root: 'data',
	totalProperty: 'total',
	fields: [
		'name',
		'from',
		'to',
		'time',
		'iso',
		'unix'

	]
});
store.load();
El código anterior ya lo conocemos muy bien, lo hemos estudiado reiteradamente en los temas anteriores, no tiene nada especial, ahora vamos a crear la tabla e introducirla dentro de una ventana de la siguiente manera:
var grid = new Ext.grid.GridPanel({
	store: store, 
	columns: [
		new Ext.grid.RowNumberer(),
		{header:'Name', dataIndex:'name',sortable: true},
		{header:'From', dataIndex:'from',sortable: true},
		{header:'To', dataIndex:'to',sortable: true},
		{header:'Time', dataIndex:'time',sortable: true},
		{header:'From ISO date', dataIndex:'iso',sortable: true},
		{header:'From Unix Time', dataIndex:'unix',sortable: true}
	],
	viewConfig: {
		forceFit: true
	},
	border: false,
	stripeRows: true
});

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

win.show();

Lo único que es importante resaltar en el código anterior es que estamos usando la propiedad “viewConfig”, esta propiedad nos permite configurar el “view” del grid que estamos creando, para este caso solamente estamos forzando a las columnas que se distribuyan sobre el grid para que todas sean mostradas.
Dates in grid

Un grid con configuraciones comunes

Problemas con el manejo de las fechas y tiempos

Si lo han notado, por alguna extraña razón no está apareciendo la información de una de las columnas, además si ordenamos ascendente o descendentemente alguna de las columnas que muestran una fecha o tiempo, no se ordenan correctamente.
Dates in grid

Errores al ordenar las columnas de fecha y tiempo

Como se aprecia en la imagen anterior, al ordenar la columna “To” de manera ascendente vemos que los meses de “Noviembre” y “Diciembre” se encuentran antes del mes de “Enero” o “Mayo”, esto es totalmente incorrecto puesto que en lugar de ordenarlos tomando en cuenta que son fechas, simplemente los está ordenando por orden alfabético como si se tratasen de palabras comunes, lo mismo sucede con la columna “Time” porque el tiempo está en formato de 12 horas así que hace el ordenamiento incorrectamente.
Dates in grid

No ordena correctamente la hora

Otro problema es que estamos mostrando una fecha en milisegundos, un usuario no podrá interpretar dicha información (Ni siquiera nosotros los desarrolladores).

Solución al problema de ordenación

Para solucionar los problemas anteriores y dar un formato más entendible para el usuario necesitamos definir en el “Store” que usaremos, los campos de tipo “date”.
var store = new Ext.data.JsonStore({
	url: 'dates.php',
	root: 'data',
	totalProperty: 'total',
	fields: [
		'name',
		{name:'from', type:'date'},
		{name:'to', type:'date'},
		{name:'time', type:'date'},
		{name:'iso', type:'date'},
		{name:'unix', type:'date'}
	]
});
store.load();

Si actualizamos la página veremos que ocurre algo inesperado:
Dates in grid

Se pierde la información de las columnas

Ha desaparecido la información que estábamos desplegando anteriormente, la pregunta es ¿por qué? ¿qué hemos hecho mal? Solamente le hemos especificado a cada campo en el “store” el tipo de dato “date”. La respuesta a las incógnitas anteriores es sencilla y ocurre porque no hemos definido el formato de la fecha o tiempo que viene del servidor, por lo tanto al convertir de “String” a “Date” sucede un error. Para solucionar esto necesitamos definir el formato por medio de la propiedad “dateFormat” de la siguiente manera:
var store = new Ext.data.JsonStore({
	url: 'dates.php',
	root: 'data',
	totalProperty: 'total',
	fields: [
		'name',
		{name:'from', type:'date', dateFormat:'m-d-Y'},
		{name:'to', type:'date', dateFormat:'j-M-Y'},
		{name:'time', type:'date', dateFormat:'h:i:s a'},
		{name:'iso', type:'date', dateFormat:'c'},
		{name:'unix', type:'date', dateFormat:'U'}
	]
});
store.load();

Si actualizamos el navegador donde estamos trabajando veremos algo semejante a la siguiente imagen.
Dates in grid

Fechas en formato ISO

Nota que ahora todas las columnas presentan la información en un mismo formato, el formato por defecto es el “iso”, inclusive para los campos en los que solamente teníamos el tiempo. Si ordenamos nuevamente las columnas podremos ver como ahora si lo hace correctamente tanto los meses como los días, horas, años, etc.

Cambiar el formato de las celdas

Ya sabemos que por medio de la propiedad “renderer” de las columnas podemos cambiar el contenido de las celdas, así que vamos a modificar el formato con el que se está mostrando las fechas utilizando una utilería del Framework.
var grid = new Ext.grid.GridPanel({
	store: store, 
	columns: [
		new Ext.grid.RowNumberer(),
		{header:'Name', dataIndex:'name',sortable: true},	
		{header:'From', dataIndex:'from',sortable: true, renderer: Ext.util.Format.dateRenderer('M/Y')},
		{header:'To', dataIndex:'to',sortable: true, renderer: Ext.util.Format.dateRenderer('M/Y')},
		{header:'Time', dataIndex:'time',sortable: true, renderer: Ext.util.Format.dateRenderer('h:i:s a')},
		{header:'From ISO date', dataIndex:'iso',sortable: true, renderer: Ext.util.Format.dateRenderer('D d M')},
		{header:'From Unix Time', dataIndex:'unix',sortable: true, renderer: Ext.util.Format.dateRenderer('M \'y')}
	],
	viewConfig: {
		forceFit: true
	},
	border: false,
	stripeRows: true
});

Utilizando el método “dateRenderer” del objeto “Ext.util.Format” podemos cambiar el formato de una manera muy sencilla, así no creamos una función para cada columna, simplemente definimos el formato que necesitamos.
Dates in grid

Formato correcto en el grid

Ahora si podemos mostrar la información de una manera muy atractiva, además puede ser ordenada correctamente.

Conclusiones

Es muy común que cuando trabajamos con fechas sucedan los errores que vimos, he recibido muchos comentarios solicitando ayuda con respecto a este tema, es por eso que creo que es importante despejar todas estas dudas. Si tienes dudas con respecto a este tema te invito a unirte al foro y participar activamente, también recuerda seguirnos en Twitter (@quizzpot) para estar pendiente de las actualizaciones, tratamos de publicar contenidos frecuentemente así que una buena idea es inscribirte a las Feeds en tu lector de RSS preferido o recibe las actualizaciones mediante correo electrónico.

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?

14Comentarios

  • Avatar-1 elcrespo 16/07/2009

    Excelente como siempre!! Gracias

    • Avatar-10 jucahoca 17/07/2009

      Ejemplos buenos y muy claros. Gracias

      • Avatar-3 narutokeen 28/07/2009

        Perfecto, fuerte y claro.gracias de nuevo

        • Avatar-12 Elías Manchón 31/10/2009

          Lo he intentado con jsp, utilizando la clase SimpleDateFormat para emular las fechas devueltas mediante php como se hace en el tutorial, al principio me funciona bien, pero ha medida que voy aplicando los formatos de Ext js hace cosas bastante raras, digamos que con JSP se invierte lo que pasa con PHP.

          • Avatar-8 Crysfel 02/11/2009

            y si estás enviando los formatos correctos? si quieres pon tu código en el foro (http://foro.quizzpot.com) Saludos

            • Avatar-10 Javier 02/11/2009

              Hola, me ha parecido genial el sitio y me preguntaba si existe alguna manera de recargar los datos del Grid cada cierto tiempo. Me gustaria actualizar mi info cada vez que algo cambia en mi base de datos. Agradecería consejos o algún ejemplo. Saludos

              • Avatar-4 Juanes 24/11/2010

                Crysfel, quería molestarte con una pregunta, y lo que sicede es que aunque aparentemente tengo bien mi código pues me carga los datos en formato m/d/Y y no d/m/Y como quisiera que sucediera...asi esta mi código: var userColumns = [ {header: "ID", width: 40, sortable: true, dataIndex: 'id'}, {header: "Nombre", width: 100, sortable: true, dataIndex: 'nombre', editor: textField}, { header: "Fecha", width: 50, sortable: true, dataIndex: 'fecha', editor: dateField, locked: false, renderer: Ext.util.Format.dateRenderer('m/d/Y') }, {header: "Hora", width: 50, sortable: true, dataIndex: 'hora', editor: timeField, increment: 5, format: 'H:i'} ]; ...asi que no entiendo por que sucede y cuando quito la línea "renderer: Ext.util.Format.dateRenderer('m/d/Y')", me cargan bien pero se me desordena de nuevo cuando intent editar el campo directamente en el grid, gracias

                • Avatar-4 lgonzales 12/01/2011

                  Quitale el renderer y agregale xtype : 'datecolumn', format : 'd/m/Y', de tal manera que quede asi: var userColumns = [ {header: "ID", width: 40, sortable: true, dataIndex: 'id'}, {header: "Nombre", width: 100, sortable: true, dataIndex: 'nombre', editor: textField}, { header: "Fecha", width: 50, sortable: true, dataIndex: 'fecha', xtype : 'datecolumn', format : 'd/m/Y', editor: dateField, locked: false }, {header: "Hora", width: 50, sortable: true, dataIndex: 'hora', editor: timeField, increment: 5, format: 'H:i'} ];

                  • Avatar-10 Daniel 18/07/2011

                    Hola, tengo un problema, cuando intento recuperar datos en un grid para fecha en el format: d/m/Y me sale menos 1 el día, en mi BD tengo 15-01-2011, en el grid sale: 14-01-2011, ¿a que se debe ese problema?

                    • Avatar-7 Martin Li causi 17/04/2012

                      hola , ami me esta pasando lo mismo, pudiste solucionarlo?

                      • Avatar-3 Everth Gallegos 18/09/2012

                        bueno yo tambien tengo el lio con que me manda la fecha con un dia menos por favor derrepente alguien logro solucionar dicho problema

                        • Avatar-9 Carlos 03/06/2013

                          No hay modo de que se visualice en mi grid el campo created_at de mi tabla document. Por supuesto se autogenera cuando construyo la bd a partir de mi schema. se que carga los datos bien, solo que no me muestra nada,si puediesen darme una respuesta me seria de gran ayuda. Saludos carlos

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

                            Estimados colegas Soy profesor de la Universidad y casi me jubilo, y en unos días gracia a la ayuda que ustedes me han brindado con su curso he podido ayudar al hijo de un amigo, no tengo con que pagarle esta ayuda, si le digo que su curso está muy interesante y sobre todo metódico, hace a uno reflexionar de las informaciones que usted brinda. Los ejemplos magnificos, hacia creo que hace 15 años que no tenia que ponerme a aprender programación y he vuelto a recordar lo aprendido gracia a lo que he podido bajar de ustedes. Se que no me pueden suministrar más información, lo entiendo y le doy las gracias un amigo que desde Cuba lo admira.

                          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.