Aprendiendo Ext JS 3

Agrupado y Sumatoria de Columnas Más videos

Descripción del tema

Ya hemos visto como editar las celdas de un Grid en tutoriales anteriores; muchas veces es necesario realizar cálculos al cambiar el valor de una celda, por ejemplo algún reporte de ventas por mes o catálogo de existencias en un almacén, etc. para realizar esto usaremos el plugin “Summary”. En este tutorial se hablará de cómo podemos agrupar en un Grid la información que cuenta con un atributo en común. Veremos cómo podemos sumar los campos que representan cierta cantidad de dinero o artículos y mostrar ese resultado en una fila de nuestro Grid. La siguiente imagen es un ejemplo de lo que tendremos al final de este tutorial:
resultado final

Resultado Final

Durante el tutorial se irá explicando el código necesario para realizar lo que se muestra en la imagen, recuerda que puedes descargar el código fuente si es necesario.

La base de datos

La información para el Grid estará en una base de datos de MySQL que contendrá una tabla llamada “destinations”, en esta tabla solo tenemos la información para poder trabajar a lo largo de este tutorial. El código para generar la tabla se muestra a continuación:
-- phpMyAdmin SQL Dump
-- version 3.2.0.1
-- http://www.phpmyadmin.net
--
-- Servidor: localhost
-- Tiempo de generación: 10-11-2010 a las 06:51:06
-- Versión del servidor: 5.1.36
-- Versión de PHP: 5.3.0

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

--
-- Base de datos: `test`
--
-- --------------------------------------------------------
--
-- Estructura de tabla para la tabla `destinations`
--

CREATE TABLE IF NOT EXISTS `destinations` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `continent` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `country` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `hotel` int(11) NOT NULL,
  `plane` int(11) NOT NULL,
  `food` int(11) NOT NULL,
  `souvenirs` int(11) NOT NULL,
  `cost` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=10 ;

--
-- Volcar la base de datos para la tabla `destinations`
--

INSERT INTO `destinations` (`id`, `continent`, `country`, `hotel`, `plane`, `food`, `souvenirs`, `cost`) VALUES
(1, 'Ameria', 'USA', 300, 900, 150, 200, 0),
(2, 'Europe', 'Spain', 300, 1100, 200, 100, 0),
(3, 'Ameria', 'Mexico', 200, 500, 150, 100, 0);
La base de datos se llama “test” pero puedes usar el nombre que te agrade, solo recuerda cambiar el nombre cuando se haga la conexión mediante PHP.

Exponer la información

Como la información está almacenada en una base de datos, necesitamos realizar la conexión vía PHP o cualquier otro lenguaje de servidor y un simple “SELECT”. El siguiente código se debe escribir en un archivo llamado “serverside/getGroups.php”.
<?php	
	$connection= mysql_connect("localhost","root","") or die("Connection Failed".mysql_error());
	mysql_select_db("test",$connection)or die("Error loading the DataBase".mysql_error());
	
	$result= mysql_query("SELECT * FROM destinations");  //step 1
	
	$data= array();
	
	while($row= mysql_fetch_array($result)){  //strp 2
		array_push($data,array(
			"id"		=> $row["id"],
			"continent"	=> $row["continent"], 
			"country"	=> $row["country"], 
			"hotel"		=> $row["hotel"],
			"plane"		=> $row["plane"],
			"food"		=> $row["food"],
			"souvenirs"	=> $row["souvenirs"],
			"cost"		=> $row["cost"]
		));
	}
	
	//step 3
	echo json_encode(
		array(  
		"success"	=> true,
		"data"		=> $data
	));
En el paso uno se hace el query que regresa todo lo que contiene la tabla “destinations”, es un query muy sencillo. En el paso dos se itera el resultset que regresó la consulta, dentro del ciclo creamos un arreglo con la información de cada uno de los contactos. En el paso cuatro se imprime la información en formato JSON, la respuesta será como el siguiente ejemplo:
{"success":true,"data":[{"id":"1","continent":"Ameria","country":"USA","hotel":"300","plane":"900","food":"150","souvenirs":"200","cost":"0"},{"id":"2","continent":"Europe","country":"Spain","hotel":"300","plane":"1100","food":"200","souvenirs":"100","cost":"0"},{"id":"3","continent":"Ameria","country":"Mexico","hotel":"200","plane":"900","food":"150","souvenirs":"100","cost":"0"}]}
Esto es suficiente para poder generar la interface del Grid mediante JavaScript ya que tenemos toda la información necesaria.

Preparando el Entorno

Para poder usar el GridSummary es necesario importar algunos archivos en nuestro archivo HTML (groupSummary-example.html). Los archivos que necesitamos son los siguientes: GroupSummary.css y GroupSummary.js.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
	
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Demo: Group Summary Example | Quizzpot</title>

<link rel="stylesheet" type="text/css" href="../ext-3.3.0/resources/css/ext-all.css" />
<link rel="stylesheet" type="text/css" href="../ext-3.3.0/examples/ux/css/GroupSummary.css" />

<script type="text/javascript" src="../ext-3.3.0/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../ext-3.3.0/ext-all.js"> </script>
<script type="text/javascript" src="../ext-3.3.0/examples/ux/GroupSummary.js"></script>

<script type="text/javascript" src="Group-Summary.js"></script>

</head>
<body>
</body>
</html>
Como podemos notar estos archivos los encontramos en el directorio donde está la librería de Ext JS en la carpeta de ejemplos donde encontraremos la carpeta ux. Si notamos solo es un archivo de estilos (.css) y un archivo de JavaScript, con estos archivos podremos cumplir lo propuesto en este tutorial. También podríamos copiarlos en una carpeta “plugins” que tengamos en nuestro proyecto, de esta manera cuando se realice el deploy del proyecto eliminamos los ejemplos, para este ejemplo los dejaremos en el directorio “ejemplos” solo para mostrar el lugar exacto donde se encuentran.

Empaquetando el Tutorial

Ya en nuestro archivo de JavaScript (Group-Summary) vamos a empaquetar el código para evitar conflictos con otras variables o librerías. Esto es algo muy importante y siempre lo debemos realizar.
Ext.ns("com.quizzpot.tutorials");

com.quizzpot.tutorials.Group = {
	init : function() {
		//code
	}
}
Ext.onReady(com.quizzpot.tutorials.Group .init,com.quizzpot.tutorials.Group );
La función “init” se ejecutará tan pronto como el DOM esté listo, por lo tanto ahí debemos colocar el código que necesitamos ejecutar primero.

Preparando la Información para el GRID

Lo primero que haremos es preparar la información que recibimos de la base de datos. Lo que necesitamos hacer es crear un JsonReader para poder interpretar la información que recibimos del servidor:
var reader = new Ext.data.JsonReader({  //step 1
	totalProperty	: 'total',
	successProperty	: 'success',
	messageProperty	: 'message',
	idProperty	: 'id',
	root		: 'data'
	},[
	//step 2
		{name: "continent", type: "string"},
		{name: "country", type: "string"},
		{name: "hotel", type: "float"},
		{name: "plane", type: "float"},
		{name: "food", type: "float"},
		{name: "souvenirs", type: "float"},
		{name: "cost", type: "float"}
	]
);
En el paso uno lo que hacemos es crear una instancia del “JsonReader” este componente nos permitirá leer e interpretar la respuesta del servidor para cada petición Ajax realizada. Lo que tenemos que notar es el atributo “messageProperty” que define la propiedad que aloja un mensaje en la respuesta del servidor, otra propiedad importante es “successProperty” la cual indicará si la operación ha sido realizada con éxito. En el paso dos colocamos los campos que conforman el “Record” que contendrá la información que usaremos en el Grid. Lo siguiente es hacer el store que tendrá al “JsonReader”, en esta ocasión veremos un nuevo tipo de store, es el “GroupingStore” este tipo de store es utilizado para agrupar la información de un Grid. Su implementación es la siguiente:
this.gstore =new Ext.data.GroupingStore({ //step 1
	url		: "serverside/getGroups.php", //step 2
	reader		: reader,
	sortInfo		: {field:"continent", direction:"ASC"},
	groupField	: "continent"
});

this.gstore.load();
En el paso uno lo que hacemos es crear la instancia del “GroupingStore”, lo que este store nos permite hacer es agrupar los registros usando uno de los campos disponibles. Notemos el atributo “groupField”, este es el atributo que se encarga de hacer lo antes mencionado. En el paso dos configuramos el “GroupingStore” de la misma manera como se configura un “JsonStore” o un “Store” a excepción del atributo “groupField” del cual hicimos mención hace uno momentos. Y por último cargamos el store.

Creando el GRID

Ya que tenemos todo listo, lo que debemos hacer es configurar el Grid para mostrar la información agrupada. Lo haremos de la siguiente manera:
//step 1
var textField = new Ext.form.TextField({allowBlank: false,}),
	numField = new Ext.form.NumberField({allowBlank: false, allowNegative: false});

this.grid = new Ext.grid.EditorGridPanel({  //step 2
	store	: this.gstore, // le pasamos el GroupStore
	columns : [  //configuración de las columnas del Grid
		{header		: "Continent",
		dataIndex	: "continent",
		hideable	: false,
		groupable	: true,
		width		: 100,
		editor		: textField,
		},{
		header		: "Country",
		dataIndex	: "country",
		groupable	: true,
		editor		: textField,
		},{
		header		: "Hotel",
		dataIndex	: "hotel",
		width		: 100,
		sortable	: true,
		groupable	: false,
		renderer	: Ext.util.Format.usMoney,
		editor		: numField,
		},{
		header		: "Plane",
		dataIndex	: "plane",
		width		: 100,
		sortable	: true,
		groupable	: false,
		renderer	: Ext.util.Format.usMoney,
		editor		: numField
		},{
		header		: "Food",
		dataIndex	: "food",
		width		: 100,
		sortable	: true,
		groupable	: false,
		renderer	: Ext.util.Format.usMoney,
		editor		: numField,
		},{
		header		: "Souvenirs",
		dataIndex	: "souvenirs",
		width		: 100,
		sortable	: true,
		groupable	: false,
		renderer	: Ext.util.Format.usMoney,
		editor		: numField,
		},{
		header		: "Total Cost",
		dataIndex	: "cost",
		width		: 100,
		sortable	: true,
		groupable	: false
		}
	], //sterp 3
	view : new Ext.grid.GroupingView({
		forceFit 			: true,
		ShowGroupName		: true,
		enableNoGroup		: false,
		enableGropingMenu	: false,
		hideGroupedColumn	: true
	}),
});
En el paso uno creamos los campos “textField” y “numField” esto con el fin de ponerlo en las columnas del Grid para que este pueda ser editado. En el paso dos solo hacemos una instancia del EditorGridPanel, y realizamos la configuración necesaria para el Grid, en el atributo store le pasamos el nuevo store como lo haríamos normalmente con los otros tipos de store. No entraremos en detalle de la configuración de las columnas del Grid pero si haremos mención de los dos nuevos atributos que usamos en la configuración de las columnas, estos son: groupable y renderer. El primero es un tributo te tipo Boolean, éste nos permite decidir si deseamos que esta columna pueda ser usada para agrupar la información del Grid. La propiedad renderer nos permite darle un formato a los campos de la columna como en esta ocasión estamos trabajando con números que representan dinero usamos “Ext.util.Format.usMoney”, si quieres conocer más al respecto de esta propiedad te recomiendo leer el tutorial que ya hemos publicado al respecto. En el paso tres hacemos el “view” que es usado por el Grid para algunas configuraciones extra relacionadas con la manera de como agrupara la información. Con esto ya tenemos nuestro Grid, los siguiente mostrarlo en una ventana:
var win = new Ext.Window({
	title	: "Destinations Summary ",
	layout	: "fit",
	width	: 550,
	height	: 300,
	items	: this.grid
});

win.show();
Con esto tendríamos algo como lo que se muestra en la siguiente imagen:
grid agrupado

Grid Agrupado

Con esto terminas el primer objetivo de nuestro tutorial. Como podemos ver los registros están agrupados bajo el campo “continente” como fue especificado en el GroupingStore.

Group Summary

Lo siguiente es crear el resumen de la información del Grid. Para esto usaremos el plugin Summary como se muestra a continuación.
var textField = new Ext.form.TextField({allowBlank: false,}),
numField = new Ext.form.NumberField({allowBlank: false, allowNegative: false});
	
//step 1
var summary = new Ext.ux.grid.GroupSummary();

//step 2
Ext.ux.grid.GroupSummary.Calculations["totalCost"] =function(v, record, field){
     return v + (record.data.hotel + record.data.plane + record.data.food + record.data.souvenirs);
};
	
this.grid = new Ext.grid.EditorGridPanel({
     store	: this.gstore,
     plugins	: summary,  //step 3
     columns : [
	//…. Configuración del las columnas del grid.
     ]
});
El código anterior está un poco resumido, pero son los mismos pasos que la sección anterior, solo le agregaremos lo que se describe a continuación. En el paso uno lo que hacemos es crear una instancia del GroupSummary para poder mostrar los resúmenes de las columnas del Grid. En el paso dos lo que hacemos es crear una nueva forma de “calculo”, como podemos ver le estamos dando el nombre de “totalCost” lo único que esto hace es ir a la columna, buscar en la fila que se especifica, tomar su valor y sumarlo a la siguiente. Es importante mencionar que es posible hacer distintos tipos de “cálculos” de esta manera. En el paso tres agregamos el Summary via plugin, con esto ya podremos usar los “cálculos” disponibles para los distintos tipos de información que se pueden manejar. Lo que sigue es realizar estos cálculos, esto ya se hace directamente en las columnas.
this.grid = new Ext.grid.EditorGridPanel({
	store	: this.gstore,
	plugins	: summary,
	columns : [
		{header		: "Continent",
		dataIndex	: "continent",
		hideable	: false,
		groupable	: true,
		width		: 100,
		editor		: textField,
		},{
		header		: "Country",
		dataIndex	: "country",
		groupable	: true,
		editor		: textField,
		//step 1
		summaryType	: "count",
		summaryRenderer: function(v, params, data){
				return ((v === 0 || v > 1) ? '(' + v +' Countries)' : '(1 Coutry)');
			}
		},{
		header		: "Hotel",
		dataIndex	: "hotel",
		width		: 100,
		sortable	: true,
		groupable	: false,
		editor		: numField,
		renderer	: Ext.util.Format.usMoney,
		//step 2
		summaryType : "sum",
		render : function(v){
			return v;
			}
		},{
		header		: "Plane",
		dataIndex	: "plane",
		width		: 100,
		sortable	: true,
		groupable	: false,
		editor		: numField,
		renderer	: Ext.util.Format.usMoney,
		summaryType : "sum",
		render : function(v){
			return v;
			}
		},{
		header		: "Food",
		dataIndex	: "food",
		width		: 100,
		sortable	: true,
		groupable	: false,
		editor		: numField,
		renderer	: Ext.util.Format.usMoney,
			summaryType : "sum",
		render : function(v){
			return v;
			}
		},{
		header		: "Souvenirs",
		dataIndex	: "souvenirs",
		width		: 100,
		sortable	: true,
		groupable	: false,
		editor		: numField,
		renderer	: Ext.util.Format.usMoney,
		summaryType : "sum",
		render : function(v){
			return v;
			}
		},{
		header		: "Total Cost",
		dataIndex	: "cost",
		width		: 100,
		sortable	: true,
		groupable	: false,
		//step 3
		renderer: function(v, params, record){
				return Ext.util.Format.usMoney(record.data.hotel + record.data.plane + record.data.food + record.data.souvenirs);
			},
		//step 4
		summaryType	: "totalCost",
		summaryRenderer: Ext.util.Format.usMoney
		}
	],
//..el código del view esta aquí
});
En el paso uno usamos “summaryType” para especificar qué tipo de cálculo queremos hacer, para este registro usaremos “count” esto con el motivo de saber cuántos registros tenemos en esta columna. El atributo “summaryRenderer” se encarga de mostrar el resultado del calculo que se realizo en el “summaryType”. En el paso dos usamos “summaryType” con “sum”, con esto sumamos todos los registros que se encuentran en esta columna. La única diferencia con el paso anterior es que usamos “render” para imprimir el resultado en el Grid, esto es porque no le estamos concatenando nada a la respuesta. Las demás columnas tienen los mismos atributos que en el paso dos ya que también queremos conocer la suma de esos campos. En el paso tres pasa algo interesante, lo primero que hacemos es hacer la suma de todos los campos que pertenecen al registro que se encuentra en esa fila, desplegamos el resultado en la columna “Total Cost” de ese registro. Para esto usamos el atributo “renderer” ya que estamos haciendo una sumatoria de los campos sin el uso de un “summaryType”. En segundo lugar usamos el “summaryType” que creamos hace unos momentos atrás, y usamos un “summaryRenderer” porque queremos modificar el resultado del “summaryType”, lo único que le agregamos es el signo de dinero. Con esto terminamos el segundo objetivo de este tutorial, hasta este momento se tiene que tener algo semejante a esto:
summeries

Summeries

Notemos algo interesante que sucede cuando editamos una de las cantidades, los campos de la columna “Total Cost” son actualizados automáticamente esto gracias a lo que sucede en la primera parte del paso tres que mencionamos hace unos instantes.

Guardando la Información

Lo que debemos hacer ahora es guardar los registros conforme van siendo editados ya que si alguno de estos registros es editado no se mostrará la información la siguiente vez que se abra la aplicación. Para esto usaremos nuestra base de datos, lo primero que haremos es agregar un “listener” al Grid que nos dirá los campos que han sido modificados y por último modificaremos esos registros en la base de datos. Usaremos el evento “afteredit” que se disparará después de que se ha editado una celda.
this.grid = new Ext.grid.EditorGridPanel({
	//configuración previo del grid
});

this.grid.on('afteredit', this.afterEdit, this );
Como podemos notar lo único que hacemos es decirle que cada vez que se edite algo en la tabla se llame a la función “afterEdit” esto mediante el evento “afteredit” también es importante mencionar que mediante “this” indicamos el scope en el que se ejecutará la función “afterEdit”. Esta función se encarga de obtener los nuevos valores de los registros editados.
afterEdit : function(e){	
	//step 1
	var recordsToSend = [];
	recordsToSend = Ext.encode(e.record.data);

	this.grid.el.mask("Saving...","x-mask-loading");
	Ext.Ajax.request({
		scope	: this,
		url		: "serverside/saveGroups.php",
		params	: {records:recordsToSend},
		success	: this.onSuccess
	});
},
Se crea la función que recibe como parámetro lo que nos manda el evento “afteredit”. En la función se crea el arreglo “recordsToSend”, con el fin de guardar en este arreglo los valores modificados. En el paso uno se realiza lo antes mencionado, usando los parámetros que mandó el evento, obtenemos la información y la codificamos para poder mandarla en la petición Ajax. En el paso dos se hace la petición Ajax, se especifica mediante el atributo “url” el archivo que tratará esta consulta. Y con “params” le decimos que es lo que enviara a ese archivo, es necesario también mencionar que en “scope” se indica donde se ejecutará la función indicada en “success”. Esta función tiene la siguiente estructura:
onSuccess	: function(response,options){
	this.grid.el.unmask();
	this.grid.getStore().commitChanges();
}
Esta función se encarga de quitar la máscara que colocamos en el Grid mientras se ejecuta la petición Ajax. También se encarga de mostrar los cambios que sufrió el Grid. El código del archivo responsable de guardar la información en la base de datos se muestra a continuación:
<?php	
	$connection=mysql_connect("localhost","root","") or die("Connection Failed".mysql_error());
	mysql_select_db("test",$connection)or die("Error loading the DataBase".mysql_error());
	
	$info = $_POST["records"];
	//step 1
	$data = json_decode(stripslashes($info));
	
	//srtep 2
	$continent	= $data->continent;
	$country	= $data->country;
	$hotel		= $data->hotel;
	$plane		= $data->plane;
	$food		= $data->food;
	$souvenirs	= $data->souvenirs;
	$cost		= $data->cost;
	
	//step 3
	$query = sprintf("UPDATE  destinations SET continent = '%s', country = '%s', hotel = %d, plane = %d, food = %d, souvenirs = %d, cost = %d WHERE country='%s' ",
		mysql_real_escape_string($continent),
		mysql_real_escape_string($country),
		mysql_real_escape_string($hotel),
		mysql_real_escape_string($plane),
		mysql_real_escape_string($food),
		mysql_real_escape_string($souvenirs),
		mysql_real_escape_string($cost),
		mysql_real_escape_string($country));

	$rs  = mysql_query($query);
	

	//step 4
	echo json_encode(array(
		"success" 	=> mysql_errno() == 0,
		"msg"		=> mysql_errno() == 0?"redor updated successfully":mysql_error()
	));
En el paso uno, una vez que recibimos la información que mandó la petición Ajax la decodificamos con la función json_decode() de PHP, con esto ya podemos acceder a la información que fue editada en el “Grid”. La función “stripslashes” elimina el carácter “\” que Apache le agrega, es posible que la configuración de tu servidor lo haga, pero es bueno prevenir esto para evitar errores en el futuro. En el paso tres obtenemos la información y la separamos en variables para poder insertarlas a la base de datos, esto es opcional ya que podríamos utilizar el mismo objeto $data. En el paso cuatro hacemos un “update” a la tabla “destinations” que es donde esta grabada la información que desplegamos en el Grid y le damos como valores la información que fue mandada mediante Ajax. En el paso cinco lo que hacemos es mandar un mensaje de éxito si es que todo sale bien, de lo contrario se manda el mensaje de error de MySQL. Con esto los registros editados serán guardados en la base de datos.

Conclusión

Hoy vimos como podemos agrupar los registro de un Grid que tienen un campo en común, también vimos como podemos usar el Summary plugin para poder resumir un la información del Grid. Esto es algo que le dará más vista a nuestras aplicaciones, una mejor experiencia a los usuarios. Te recordamos que puedes usar “user voice” para darnos ideas de los tutoriales que se pueden publicar en este sitio, también puedes votar por las ideas que más te gusten. También tenemos un foro donde puedes realizar tu preguntas, la comunidad está creciendo poco a poco y hay varios miembros dispuestos a ayudarte en tus dudas.

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?

16Comentarios

  • Avatar-9 Karo Fonse 10/12/2010

    Muchas gracias Victor, muy bueno tu turorial y super bien explicado paso a paso me ayudado muchisimo...

    • Avatar-10 JaimeS 13/12/2010

      Que tal mi buen victor justamente algo de esto estaba ocupando para complementar un ejemplo, pero me encontre que al instancear al "GroupingView" 2 propiedades no tienen bien su nombre: enableNoGroup =&gt; enableNoGroups enableGropingMenu =&gt; enableGroupingMenu fuera de eso es muy bien el ejemplo muchas gracias.

      • Avatar-6 Merly 09/01/2011

        Hola Victor, primero agradecerte por el gran tema y por tu tiempo Bueno estoy realizando algo así como una factura pero con más datos, estos datos en su mayoría son calculables y necesito almacenarlos en mi bd, me gustaría que me des una idea de cómo guardarlos a mi bd puesto que como se puede visualizar el valor calculado pero como el value de estos campos es vacio me los guarda como 0.0 Agradecería su ayuda.

        • Avatar-5 LOJARA 03/02/2011

          Hola Felipe. Te agradezco por tu excelente material, y sobre todo por el tiempo que te tomas en realizar estos materiales, gracias por enseñarme sobre este blog.

          • Avatar-9 Gustavo 30/05/2011

            Excelente!! Gracias! me maté para poder hacer esto y ahora veo lo sencillo que es... sencillo cuando esta bien hecho. Me pasa con los ejemplos de sencha que no los puedo adaptar a mi aplicacion porque son muy extensos y me cuesta sacar lo que no quiero poner, pero en estos tutoriales esta tan bien armado que es facil adaptarlo a lo que uno quiere. Salduos y gracias por compartir tus conocimientos.

            • Avatar-3 wallz 02/06/2011

              Bien compadre, buen trabajo y bien explicado, buen tutor. saludos Wallz

              • Avatar-3 Miguel Cespedes 17/06/2011

                Me gustaria saber si existe alguna propiedad que me muestre los grupos colapsados al inicio.

                • Avatar-7 Victor Felipe 22/06/2011

                  disculpa por contestar tiempo después... mira la propiedad que muestra los grupos colapsados se configura en el view y es startCollapsed la cual tienes que ser verdadero(true). esta por defecto es false. suerte, y espero que esto te ayude...

                  • Avatar-4 Ismael Saenz 24/06/2011

                    Se puede hacer esto pero en una aplicación de escritorio con swing en java?

                    • Avatar-1 HackHades 27/09/2011

                      Excelente amigo! me gustaría saber si existe alguna propiedad para ordenar los grupos de manera descendente, en este caso los continentes, por ejemplo primero oceania,europa y por ultimo america; no se si me di a entender pero para aclarar no me refiero a los campos internos sino a los grupos en si :-) muy agradecido...

                      • Avatar-2 Rodolfo 02/11/2011

                        Hola, espero que se encuentren bien, con una duda que no encuentro en la red, cuando se aplica la funcion que se muestra abajo summaryRenderer: function(v, params, data){ return ((v === 0 || v &gt; 1) ? '(' + v +' Countries)' : '(1 Coutry)'); } enfocado al ejemplo aqui planteado como puedo obtener el nombre del continente dentro de la funcion summaryRenderer, saludos y gracias. . .

                        • Avatar-4 Daney 28/03/2012

                          Debes tener un registro por el cual puedas agrupar y colocarlo de cabecera. ese "(1 Coutry)" indica si es un solo registro o si por el contrario son varios registros "( v +’ Countries)"

                          • Avatar-5 jesus 01/06/2012

                            con que version de extjs esta hecho este ejemplo?

                            • Avatar-5 yoel 06/09/2012

                              es necesario que el grid cuente con datos o sea el store se cargue con los datos que estan en la DB estoy tratando de sumar dos campos que introdusco en el grid para depues enviarlos a la DB pero no suma nada me pone NaN supongo que la funcion no encuentra que sumar...

                              • Avatar-6 perla 20/06/2013

                                Hola! me gustaria saber cual es la propiedad para que cuando se muestre el grid agrupado este colapsado Gracias

                                • Avatar-10 Victor Felipe 21/06/2013

                                  la propiedad que muestra los grupos colapsados se configura en el view y es startCollapsed la cual tienes que ser verdadero(true)

                                  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.