<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Quizzpot &#187; Ext3</title>
	<atom:link href="http://www.quizzpot.com/category/ext-js/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.quizzpot.com</link>
	<description>Cursos en video gratuitos</description>
	<lastBuildDate>Fri, 09 Dec 2011 11:38:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Bleextop &#8211; Un desktop con Ext4 y CodeIgniter</title>
		<link>http://www.quizzpot.com/2011/08/bleextop-un-desktop-con-ext4-y-codeigniter/</link>
		<comments>http://www.quizzpot.com/2011/08/bleextop-un-desktop-con-ext4-y-codeigniter/#comments</comments>
		<pubDate>Wed, 10 Aug 2011 15:53:37 +0000</pubDate>
		<dc:creator>Crysfel</dc:creator>
				<category><![CDATA[Español]]></category>
		<category><![CDATA[Ext3]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.quizzpot.com/?p=2940</guid>
		<description><![CDATA[El día de hoy quiero anunciar un proyecto en el que vengo trabajando desde hace más de un mes, Bleextop es la realización de una idea que tengo desde hace ya mucho tiempo y se trata de crear un proyecto base con las funcionalidades genéricas para poder ser utilizado en cualquier otro proyecto.]]></description>
			<content:encoded><![CDATA[<p>El día de hoy quiero anunciar un proyecto en el que vengo trabajando desde hace más de un mes, Bleextop es la realización de una idea que tengo desde hace ya mucho tiempo y se trata de crear un proyecto base con las funcionalidades genéricas para poder ser utilizado en cualquier otro proyecto.</p>
<p><a href="http://demos.bleext.com/desktop/">Bleextop</a> es un Desktop con <a href="http://www.sencha.com/products/extjs/">ExtJS4</a> y <a href="http://codeigniter.com/">CodeIgniter</a>, actualmente cuenta con las siguientes características:</p>
<ul>
<li>Un sistema de Login/Logout</li>
<li>Un sistema ACL para manejo de roles y permisos a los módulos del sistema</li>
<li>Sistema de notificaciones semejantes a las de “Growl” de MacOS.</li>
<li>Un menu dinámico inicial basado en roles y permisos configurables</li>
<li>Wallpaper con opción a colocarlo en 3 posiciones. (centrado, estirado y tapiz)</li>
<li>Accesos directos en el escritorio configurables.</li>
<li>Sistema de administación de ventanas y barra de tareas.</li>
<li>Sistema de carga dinámica de las aplicaciones.</li>
<li>Un módulo para administrar las aplicaciones</li>
<li>Un módulo para administrar los roles y usuarios con drag and drop (semejante al de G+)</li>
<li>Accesos diréctos en la barra de tareas</li>
</ul>
<p>El código ya se <a href="https://github.com/crysfel/Bleextop">encuentra en GitHub</a> y puede ser descargable para ser probado, también pueden <a href="http://demos.bleext.com/desktop/">ver un demo</a> que he preparado (<strong>usr:crysfel,passwd:123</strong>), es importante mencionar que esta en fase de desarrollo y todavía no está terminado al 100%.</p>
<p>Hacen falta muchas cosas y seguramente hay varios bugs, pero el proyecto tiene mucho futuro y además será de mucha utilidad para todos, pronto iniciaré a sacar tutoriales para como utilizarlo, pero primero quiero tener una versión más estable.</p>
<p>Bleextop será liberado OpenSource y la idea es que pueda llegar a crecer y ser usado por muchos desarrolladores alrededor del mundo, por el momento busco ayuda de testers y desarrolladores para poder avanzar más rápido, yo mismo ya estoy usando este proyecto con unos de mis clientes y le voy corrigiendo varias cosas pero siempre es bueno contar con ayuda de otros desarrolladores.</p>
<p>Comentarios y sugerencias ya saben que son bien recibidas! además no olviden <a href="http://foro.quizzpot.com/">registrarse en el foro</a> para pertenecer a la comunidad y colaborar con los proyectos e ideas que tenemos.</p>
<h3>Imágenes</h3>
<p><img src="http://www.quizzpot.com/wp-content/uploads/2011/08/bleextop-01.png" alt="" title="bleextop-01" /><br />
<img src="http://www.quizzpot.com/wp-content/uploads/2011/08/bleextop-02.png" alt="" title="bleextop-01" /><br />
<img src="http://www.quizzpot.com/wp-content/uploads/2011/08/bleextop-03.png" alt="" title="bleextop-01" /><br />
<img src="http://www.quizzpot.com/wp-content/uploads/2011/08/bleextop-04.png" alt="" title="bleextop-01" /><br />
<img src="http://www.quizzpot.com/wp-content/uploads/2011/08/bleextop-05.png" alt="" title="bleextop-01" /><br />
<img src="http://www.quizzpot.com/wp-content/uploads/2011/08/bleextop-06.png" alt="" title="bleextop-01" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.quizzpot.com/2011/08/bleextop-un-desktop-con-ext4-y-codeigniter/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>ExtJs y Sencha Touch Themes</title>
		<link>http://www.quizzpot.com/2011/02/extjs-y-sencha-touch-themes/</link>
		<comments>http://www.quizzpot.com/2011/02/extjs-y-sencha-touch-themes/#comments</comments>
		<pubDate>Wed, 23 Feb 2011 14:00:04 +0000</pubDate>
		<dc:creator>Crysfel</dc:creator>
				<category><![CDATA[Español]]></category>
		<category><![CDATA[Ext3]]></category>

		<guid isPermaLink="false">http://www.quizzpot.com/?p=2925</guid>
		<description><![CDATA[ExtJs es una excelente librería para desarrollar aplicaciones web tipo desktop, además está en constante desarrollo y cuenta con una gran comunidad de desarrolladores alrededor de esta.]]></description>
			<content:encoded><![CDATA[<p>ExtJs es una excelente librería para desarrollar aplicaciones web tipo desktop, además está en constante desarrollo y cuenta con una gran comunidad de desarrolladores alrededor de esta.</p>
<p>Durante cada cambio de versión que se ha publicado han aparecido principalmente dos temas, el <a href="http://dev.sencha.com/deploy/dev/examples/themes/index.html">clásico azul claro</a> y uno de color gris, por otro lado la comunidad ha creado herramientas para facilitar el cambiar la tonalidad de los temas por defecto e inclusive se han creado algunos otros temas con un diseño diferente.</p>
<p>Pero la realidad es que hay muy pocos temas circulando por la red y quizás no de la calidad que quisiéramos, es por esto que ha nacido “<a href="http://www.bleext.com/">Bleext</a>”, un sitio dedicado a la creación de temas para ExtJs y Sencha Touch, la idea es crear temas de calidad diseñados con detalle y de fácil instalación.</p>
<p>Por el momento solo <a href="http://www.bleext.com/products/elegant-black-theme/">cuenta con un tema</a> pero pronto aparecerán más, también si algún diseñador se anima a realizar algún tema pero se le dificulta la creación del CSS con gusto le podemos ayudar a codificarlo correctamente.</p>
<p>También se planea publicar tutoriales sobre como diseñar y codificar tus propios temas para uso personal o bien para venderlos en la plataforma que estamos desarrollando en estos momentos.</p>
<p>Por último les invito a seguirnos en <a href="http://twitter.com/bleext">Twitter @bleext</a>  o <a href="http://www.facebook.com/pages/Bleext/167750333272350">Facebook</a> para estar pendiente de los nuevos temas que se vayan publicando.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.quizzpot.com/2011/02/extjs-y-sencha-touch-themes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Agrupado y Sumatoria de Columnas</title>
		<link>http://www.quizzpot.com/2010/11/agrupado-y-sumatoria-de-columnas/</link>
		<comments>http://www.quizzpot.com/2010/11/agrupado-y-sumatoria-de-columnas/#comments</comments>
		<pubDate>Tue, 30 Nov 2010 16:56:21 +0000</pubDate>
		<dc:creator>Victor Felipe</dc:creator>
				<category><![CDATA[Español]]></category>
		<category><![CDATA[Ext3]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.quizzpot.com/?p=2854</guid>
		<description><![CDATA[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”.]]></description>
			<content:encoded><![CDATA[<p>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.</p>
<p>La siguiente imagen es un ejemplo de lo que tendremos al final de este tutorial:</p>
<p><!-- imagen 1 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/11/agrupado-sumatoria-1.png" alt="resultado final" />
<p>Resultado Final</p>
</div>
<p>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.</p>
<h3>La base de datos</h3>
<p>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:</p>
<pre name="code" class="sql">
-- 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);
</pre>
<p>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.</p>
<h3>Exponer la información</h3>
<p>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”.</p>
<pre name="code" class="php">
&lt;?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"		=&gt; $row["id"],
			"continent"	=&gt; $row["continent"],
			"country"	=&gt; $row["country"],
			"hotel"		=&gt; $row["hotel"],
			"plane"		=&gt; $row["plane"],
			"food"		=&gt; $row["food"],
			"souvenirs"	=&gt; $row["souvenirs"],
			"cost"		=&gt; $row["cost"]
		));
	}

	//step 3
	echo json_encode(
		array(
		"success"	=&gt; true,
		"data"		=&gt; $data
	));
</pre>
<p>En el paso uno se hace el query que regresa todo lo que contiene la tabla “destinations”, es un query muy sencillo.</p>
<p>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.</p>
<p>En el paso cuatro se imprime la información en formato JSON, la respuesta será como el siguiente ejemplo:</p>
<pre name="code" class="javascript">
{"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"}]}
</pre>
<p>Esto es suficiente para poder generar la interface del Grid mediante JavaScript ya que tenemos toda la información necesaria.</p>
<h3>Preparando el Entorno</h3>
<p>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.</p>
<pre name="code" class="html">
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;

&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&gt;
&lt;title&gt;Demo: Group Summary Example | Quizzpot&lt;/title&gt;

&lt;link rel="stylesheet" type="text/css" href="../ext-3.3.0/resources/css/ext-all.css" /&gt;
&lt;link rel="stylesheet" type="text/css" href="../ext-3.3.0/examples/ux/css/GroupSummary.css" /&gt;

&lt;script type="text/javascript" src="../ext-3.3.0/adapter/ext/ext-base.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="../ext-3.3.0/ext-all.js"&gt; &lt;/script&gt;
&lt;script type="text/javascript" src="../ext-3.3.0/examples/ux/GroupSummary.js"&gt;&lt;/script&gt;

&lt;script type="text/javascript" src="Group-Summary.js"&gt;&lt;/script&gt;

&lt;/head&gt;
&lt;body&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p> 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. </p>
<p>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.</p>
<h3>Empaquetando el Tutorial</h3>
<p>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.</p>
<pre name="code" class="javascript">
Ext.ns("com.quizzpot.tutorials");

com.quizzpot.tutorials.Group = {
	init : function() {
		//code
	}
}
Ext.onReady(com.quizzpot.tutorials.Group .init,com.quizzpot.tutorials.Group );
</pre>
<p>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.</p>
<h3>Preparando la Información para el GRID</h3>
<p>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:</p>
<pre name="code" class="javascript">
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"}
	]
);
</pre>
<p>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.</p>
<p>En el paso dos colocamos los campos que conforman el “Record” que contendrá la información que usaremos en el Grid.</p>
<p>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:</p>
<pre name="code" class="javascript">
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();
</pre>
<p>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.</p>
<p>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.</p>
<h3>Creando el GRID</h3>
<p>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:</p>
<pre name="code" class="javascript">
//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
	}),
});
</pre>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>Con esto ya tenemos nuestro Grid, los siguiente mostrarlo en una ventana:</p>
<pre name="code" class="javascript">
var win = new Ext.Window({
	title	: "Destinations Summary ",
	layout	: "fit",
	width	: 550,
	height	: 300,
	items	: this.grid
});

win.show();
</pre>
<p>Con esto tendríamos algo como lo que se muestra en la siguiente imagen:</p>
<p><!-- imagen 2 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/11/agrupado-sumatoria-2.png" alt="grid agrupado" />
<p>Grid Agrupado</p>
</div>
<p>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.</p>
<h3>Group Summary </h3>
<p>Lo siguiente es crear el resumen de la información del Grid. Para esto usaremos el plugin Summary como se muestra a continuación.</p>
<pre name="code" class="javascript">
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.
     ]
});
</pre>
<p>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. </p>
<p>En el paso uno lo que hacemos es crear una instancia del GroupSummary para poder mostrar los resúmenes de las columnas del Grid.</p>
<p>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.</p>
<p>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.</p>
<p>Lo que sigue es realizar estos cálculos, esto ya se hace directamente en las columnas.</p>
<pre name="code" class="javascript">
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 &gt; 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í
});
</pre>
<p>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. </p>
<p>El atributo “summaryRenderer” se encarga de mostrar el resultado del calculo que se realizo en el “summaryType”. </p>
<p>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.<br />
Las demás columnas tienen los mismos atributos que en el paso dos ya que también queremos conocer la suma de esos campos.</p>
<p>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”.<br />
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.</p>
<p>Con esto terminamos el segundo objetivo de este tutorial, hasta este momento se tiene que tener algo semejante a esto:</p>
<p><!-- imagen 3 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/11/agrupado-sumatoria-1.png" alt="summeries" />
<p>Summeries</p>
</div>
<p>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.</p>
<h3>Guardando la Información</h3>
<p>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.</p>
<p>Usaremos el evento “afteredit” que se disparará después de que se ha editado una celda.</p>
<pre name="code" class="javascript">
this.grid = new Ext.grid.EditorGridPanel({
	//configuración previo del grid
});

this.grid.on('afteredit', this.afterEdit, this );
</pre>
<p>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.</p>
<pre name="code" class="javascript">
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
	});
},
</pre>
<p>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.</p>
<p>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.</p>
<p>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”.</p>
<p>Esta función tiene la siguiente estructura:</p>
<pre name="code" class="javascript">
onSuccess	: function(response,options){
	this.grid.el.unmask();
	this.grid.getStore().commitChanges();
}
</pre>
<p>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.</p>
<p>El código del archivo responsable de guardar la información en la base de datos se muestra a continuación:</p>
<pre name="code" class="php">
&lt;?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-&gt;continent;
	$country	= $data-&gt;country;
	$hotel		= $data-&gt;hotel;
	$plane		= $data-&gt;plane;
	$food		= $data-&gt;food;
	$souvenirs	= $data-&gt;souvenirs;
	$cost		= $data-&gt;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" 	=&gt; mysql_errno() == 0,
		"msg"		=&gt; mysql_errno() == 0?"redor updated successfully":mysql_error()
	));
</pre>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>Con esto los registros editados serán guardados en la base de datos.</p>
<h3>Conclusión</h3>
<p>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.</p>
<p>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.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.quizzpot.com/2010/11/agrupado-y-sumatoria-de-columnas/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Integración del FormPanel y el GridPanel</title>
		<link>http://www.quizzpot.com/2010/11/integracion-del-formpanel-y-el-gridpanel/</link>
		<comments>http://www.quizzpot.com/2010/11/integracion-del-formpanel-y-el-gridpanel/#comments</comments>
		<pubDate>Thu, 11 Nov 2010 15:00:14 +0000</pubDate>
		<dc:creator>Victor Felipe</dc:creator>
				<category><![CDATA[Español]]></category>
		<category><![CDATA[Ext3]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.quizzpot.com/?p=2809</guid>
		<description><![CDATA[En esta ocasión vamos a Crear, Leer, Actualizar y Borrar (CRUD) un catalogo de contactos usando un formulario y mostrando los resultados en un “Grid” este es el que se encargara de hacer las operaciones antes mencionadas, con esto veremos otra aplicación básica de la integración de un FormPanel y el GridPanel, utilizando un Writer dentro del Store que maneja el Grid.]]></description>
			<content:encoded><![CDATA[<p>En este tutorial haremos un CRUD para poder editar la información contenida en el Grid, esto lo lograremos mediante el Writter de un store y usaremos un formulario para poder editar esa información.</p>
<p>La siguiente imagen es un ejemplo de lo que tendremos al final de este tutorial.</p>
<p><!-- imagen 1 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/11/crud-form-1.png" alt="resultado final" />
<p>Resultado Final</p>
</div>
<p>Durante el tutorial se irá explicando el código necesario para realizarlo, recuerda que puedes descargar el código fuente si te es necesario.</p>
<h3>La Base de datos</h3>
<p>La información para el Grid estará en una base de datos de MySQL que contendrá una tabla llamada “contacts”, en esta tabla solo tenemos la información básica de un contacto. El código para generar la tabla se muestra a continuación.</p>
<pre name="code" class="sql">
-- phpMyAdmin SQL Dump
-- version 3.2.0.1
-- http://www.phpmyadmin.net
--
-- Servidor: localhost
-- Tiempo de generación: 28-10-2010 a las 16:30:53
-- 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 `contacts`
--

CREATE TABLE IF NOT EXISTS `contacts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `firstName` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `lastName` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `age` varchar(3) COLLATE utf8_unicode_ci NOT NULL,
  `phone` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `country` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=5 ;

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

INSERT INTO `contacts` (`id`, `email`, `firstName`, `lastName`, `age`, `phone`, `country`) VALUES
(1, 'luiz@gmail.com', 'Luiz', 'Ortega', '19', '123 - 456 - 7893', 'Mexico'),
(2, 'sasha@gmail.com', 'Sasha', 'Cohen', '25', '123 - 456 - 7892', 'USA'),
(3, 'cr@gmail.com', 'Cristiano', 'Ronaldo', '24', '123 - 456 - 7891', 'Portugal'),
(4, 'john@hotmail.com', 'John', 'Smith', '21', '123 - 456 - 7894', 'USA');
</pre>
<p>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.</p>
<h3>Exponer la información</h3>
<p>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” de la siguiente manera. El siguiente código se debe escribir en un archivo llamado “serverside/getContacts.php”.</p>
<pre name="code" class="php">
&lt;?php	//step 1
	$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 contacts");  //step 2

	$data= array();

	while($row= mysql_fetch_array($result)){  //step 3
		array_push($data,array(
			"id"	=&gt; $row["id"],
			"first"	=&gt; $row["firstName"],
			"last"	=&gt; $row["lastName"],
			"email"	=&gt; $row["email"],
			"age"	=&gt; $row["age"],
			"phone"	=&gt; $row["phone"],
			"country"=&gt;$row["country"]
		));
	}

	echo json_encode(  //step 4
		array(
		"success"	=&gt; true,
		"data"		=&gt; $data
	));
</pre>
<p>En el paso uno se realiza la conexión a la base de datos, recuerda que debes poner las credenciales adecuadas así como la base de datos que usarás, en mi caso es “test”.</p>
<p>En el paso dos se hace el query que regresa todo lo que contiene la tabla “contacts”, es un query muy sencillo.<br />
En el paso tres se itera el resultset que regresó la consulta, dentro del ciclo creamos un arreglo con la información de cada uno de los contactos.</p>
<p>En el paso cuatro se imprime la información en formato JSON, la respuesta será como el siguiente ejemplo: </p>
<pre name="code" class="javascript">
{"success":true,"data":[{"id":"1","first":"Luiz","last":"Ortega","email":"luiz@gmail.com","age":"19","phone":"123 - 456 - 7893","country":"Mexico"},{"id":"2","first":"Sasha","last":"Cohen","email":"sasha@gmail.com","age":"25","phone":"123 - 456 - 7892","country":"USA"},{"id":"3","first":"Cristiano","last":"Ronaldo","email":"cr@gmail.com","age":"24","phone":"123 - 456 - 7891","country":"Portugal"},{"id":"4","first":"John","last":"Smith","email":"john@hotmail.com","age":"21","phone":"123 - 456 - 7894","country":"USA"}]}
</pre>
<p>Esto es suficiente para poder generar la interface del Grid mediante JavaScript ya que tenemos toda la información necesaria.</p>
<h3>Empaquetando el Tutorial</h3>
<p>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.</p>
<pre name="code" class="javascript">
Ext.ns("com.quizzpot.tutorials");

com.quizzpot.tutorials.CrudForm = {
	init : function() {
		//code
	}
}
Ext.onReady(com.quizzpot.tutorials.CrudForm.init,com.quizzpot.tutorials.CrudForm);
</pre>
<p>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.</p>
<h3>Creando el CRUD</h3>
<p>Lo que haremos a continuación es solicitar la información al servidor, esto será ya dentro de la función “init” de nuestro archivo “crudexample.js”. Como mencionamos anteriormente usaremos un “writer” que se encargue de hacer las operaciones básicas (leer, escribir, modificar y eliminar). Para logara esto es necesario definir la propiedad “api” con las URLs donde el “proxy” realizara las peticiones Ajax de manera automática. </p>
<pre name="code" class="javascript">
var proxy = new Ext.data.HttpProxy({  //step 1
	api: {
		read 	: "serverside/getContacts.php",
		create 	: "serverside/createContact.php",
		update	: "serverside/updateContact.php",
		destroy	: "serverside/destroyContact.php"
	}
});
</pre>
<p>En el paso uno se crea una instancia de “Ext.data.HttpProxy” esto es para que el “store” realice las peticiones Ajax de manera automática.</p>
<p>A continuación haremos el “Reader” y el “Writer”:</p>
<pre name="code" class="javascript">
var reader = new Ext.data.JsonReader({  //step 1
	totalProperty	: 'total',
	successProperty	: 'success',   // indica la propiedad que define si se ha insertado/actualizado o borrado con éxito
	messageProperty	: 'message',
	idProperty	: 'id',
	root		: 'data'   //este es el nombre del parámetro que llega al servidor con el JSON modificado
},[
	{name: 'first'},
	{name: 'last'},
	{name: 'email'}
]);

var writer = new Ext.data.JsonWriter({  //step 2
	encode		: true,
	writeAllFields	: true  //decide si se manda al servidor solamente los campos modificados o todo
})

this.store = new Ext.data.Store({
	proxy		: proxy,
	reader		: reader,
	writer		: writer,
	autoSave	: true
});
this.store.load();
</pre>
<p>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.</p>
<p>En el paso tres se crea la instancia del “JsonWriter”.</p>
<p>Los tres fragmentos de código anteriores ya los hemos visto a detalle en tutoriales pasados, esa es la razón por la que no entramos a detalles de estructura solo hacemos mención algunos atributos. Si esto es nuevo para ti, te recomendamos revisar el tema sobre esto.//link a lo onda del CRUD <img src='http://www.quizzpot.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<h3>Creado el Grid</h3>
<p>A continuación crearemos el Grid. Lo primero que haremos es desplegar la información que traemos desde la base de datos.</p>
<pre name="code" class="javascript">
var sm = new Ext.grid.CheckboxSelectionModel(); //step 1

 this.grid = new Ext.grid.GridPanel({  .//step 2
	region		: "center",
	margins		: "3 3 3 3",
	width		: 300,
	store		: this.store, // step 3
	columns		: [
			sm,
			{header:'Name', dataIndex:'first',sortable: true,width:80},
			{header:'Lastname', dataIndex:'last',sortable: true,width:80},
			{header:'E-mail', dataIndex:'email',sortable: true,width:100}
			],
tbar		: [   //step  4
			{text:"Delete", scope:this, handler:this.onDelete,iconCls:'delete-icon'}
			],
 	sm		: sm,
	border		: false,
	stripeRows	: true
});
</pre>
<p>En el paso uno creamos una instancia del componente “CheckboxSelectionModel” para hacer que el selectionModel funcine mediante un checkbox.</p>
<p>En el paso dos se crea la instancia del GridPanel para formar la tabla que contendrá la información recibida de la base de datos.</p>
<p>Notemos que esta tabla cuenta con el dos atributos especiales “region” y “margins” el primero es para poder colocar nuestra tabla en una ventana que use un layout de tipo “border”. Por esta razón nuestro tabla tiene este atributo el cual nos dice que queremos que la tabla esté en el centro de la ventana. El segundo solo crea un margen alrededor del componente a la distancia en pixeles que le especificamos.</p>
<p>En el paso tres se le pasa a la tabla el “store” que contiene la información a desplegar en el grid.</p>
<p>En el paso cuatro se está agregando el botón “eliminar” en la barra de herramientas. Notemos que al botón se le está agregando una imagen para esto es necesario  definir la case CSS (delete-icon) en nuestra hoja de estilos o documento HTML de la siguiente manera:</p>
<pre name="code" class="css">
.delete-icon{background:transparent url(icons/delete.png) 0 0 no-repeat !important;}
</pre>
<p>Por el momento no trabajaremos con la función que está en el botón ya que lo haremos un poco más adelante así que puedes comentar el atributo “handler”.</p>
<p>Por último colocaremos nuestra tabla en una ventana para poder mostrar los registros de esta. </p>
<pre name="code" class="javascript">
var win = new Ext.Window({
	title	: "Grid and Form Example",
	layout	: "border",
	width	: 600,
	height	: 400,
	items	: [this.grid]
});
win.show();
</pre>
<p>Este es código ya muy común para nosotros. Solo mencionaremos algo relacionado con lo anterior, si notamos esta ventana tiene un layout de tipo “border” esto con el fin de acomodar los componentes en regiones. Por el momento solo contamos con nuestra tabla. </p>
<p>En estos momentos tendríamos algo semejante a esto:</p>
<p><!-- imagen 2 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/11/crud-form-2.png" alt="colocando el grid" />
<p>Colocando el Grid</p>
</div>
<h3>Creado el Formulario</h3>
<p>En la sección pasada creamos la tabla que muestra la información de la base de datos, ahora haremos el formulario para introducir y editar la información.</p>
<p>Lo primero que haremos es crear el formulario.</p>
<pre name="code" class="javascript">
this.form = new Ext.form.FormPanel({
	region		: "west",
	width		: 250,
	bodyStyle	: "padding: 10px;",
	url		: "serverside/updateContact.php", //step 1
	margins		: "3 3 3 3",
	border		: false,
	defaults		: {allowBlank: false},
	items		: [  //sptep 2
			{xtype : "textfield", name : "first", fieldLabel : "Name"},
			{xtype : "textfield", name : "last", fieldLabel : "Lastname"},
			{xtype : "textfield", name : "email", fieldLabel : "E-mail", vtype :"email"},
			{xtype : "textfield", name : "age", fieldLabel : "Age"},
			{xtype : "textfield", name : "phone", fieldLabel : "Phone"},
			{xtype : "textfield", name : "country", fieldLabel : "Contry"},
			{xtype : "textfield", name : "id",hidden:true,allowBlank:true}
			],			],
	fbar		: [{text : "Update", scope : this, handler: this.onUpdate},  //step 3
			   {text : "Create", scope : this, handler: this.addContact}],
});
</pre>
<p>Lo primero que hacemos es crear la instancia del FormPanel.</p>
<p>Si notamos nuestro formulario cuenta con los atributos “region” y “margins” del mismo modo que en la sección anterior nuestra tabla. El tributo región coloca el formulario en la posición “oeste” y “margins” crea un margen alrededor del formulario.</p>
<p>En el paso uno específicas con el atributo “url” el archivo que manejara el evento “submit” del formulario, esto lo veremos un poco más adelante.</p>
<p>En el paso dos tenemos los campos que formarán el formulario, en general todos los “textfields” solo cuentan con un “nombre” y su “etiqueta”. Notemos el caso de el campo que recibe el correo electrónico que introduce el usuario, este cuenta con un “vtype” de tipo “email” esto es con el fin de validar que el usuario ingrese una dirección de correo electrónico válida al un cambio o crear un nuevo contacto.</p>
<p>El campo de nombre “id” también es un caso especial, si notamos este campo está oculto ya que lo definimos así por medio del atributo “hidden”, este campo se puede quedar en blanco. El por qué de esto lo explicaremos más adelante.</p>
<p>En el paso tres se crean los botones “actualizar” y “crear”. Por el momento no trabajaremos con las funciones que están en los botones ya que lo haremos un poco más adelante así que puedes comentar el atributo “handler”.</p>
<p>Ya que tenemos el formulario listo lo siguiente es agregarlo a la venta, para poder mostrarlo.</p>
<pre name="code" class="javascript">
var win = new Ext.Window({
	title	: "Grid and Form Example",
	layout	: "border",
	width	: 600,
	height	: 400,
	items	: [this.grid,this.form] //step 1
});
win.show();
</pre>
<p>En el paso uno solo agregamos el formulario a la ventana por medio del atributo “items”, en este momento deberíamos tener algo como la siguiente imagen:</p>
<p><!-- imagen 3 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/11/crud-form-3.png" alt="colocando el formulario" />
<p>Colocando el Formulario</p>
</div>
<h3>Grabar los Registros Modificados </h3>
<p>Hasta este punto tenemos la información en nuestro “Grid” lo siguiente que tenemos que hacer para poder cumplir una de las funciones del CRUD es editar los registros del “Grid” y guardarlos en la base de datos.</p>
<p>Para esto tenemos que sacar la información del Grid y desplegarlo en el formulario. Lo primero que haremos es desplegar la información del Grid en el formulario, con la información ya en el formulario la podremos editar y guardar en la base de datos.</p>
<p>Lo primero que haremos es obtener la información del contacto, esto lo haremos de la siguiente manera:</p>
<p>this.grid.on(&#8220;rowClick&#8221;,this.loadRecord,this);</p>
<p>Agregamos el evento “rowClick”, este evento se dispara cuando se da clic sobre un registro de la tabla, notemos que este evento es manejado por la función “loadRecord” es importante mencionar que también se le pasa el scope donde se ejecutará la función.</p>
<p>La función loadRecord lo que hace es hacer una petición al servidor con el “id” del contacto para traer la información de este y desplegarla en el formulario, esta función la veremos a continuación:</p>
<pre name="code" class="javascript">
loadRecord : function(Grid,index,ev){  //step 1
	var rec = this.grid.store.getAt(index);  //step 2

	this.form.getForm().load({  //step 3
		url	: "serverside/fillForm.php", //archivo php que se encargará de hacer la petición al servidor
		params	: {record:rec.id},  //step 4
		failure	: function(form, action){
		Ext.Msg.alert("Error","Load failed");
		}
});
},
</pre>
<p>En el paso uno se crea la función recibiendo los parámetros que nos manda el evento “rowClick”.</p>
<p>En el paso dos usamos el parámetro “index” el cual nos marca la fila en la que se encuentra el registro sobre el cual se dio clic. Esto lo hacemos con el fin de obtener la información de ese registro para poder cargarla en el formulario.</p>
<p>En el paso tres usamos el método “load” para cargar hacer la petición Ajax y desplegar el resultado en el formulario. </p>
<p>En el paso cuatro como parámetro de la petición mandamos el “id” del registro el cual obtuvimos en el paso uno.</p>
<p>Con esto es suficiente para hacer la petición al servidor, lo que sigue es crear el archivo PHP (serverside/fillForm.php) que  es el que se comunicará con la base de datos.</p>
<pre name="code" class="php">
&lt;?php	//step 1
$connection = mysql_connect("localhost","root","") or die("Connection Failed".mysql_error());
	mysql_select_db("test",$connection)or die("Error loading the DataBase".mysql_error());

	$id = $_POST["record"];
	//step 2
	$query = sprintf("SELECT * FROM contacts WHERE id =%d",
			mysql_real_escape_string($id));

	$result = mysql_query($query);

	$info=array();
	//step 3
	if($row = mysql_fetch_array($result)){
		$info = array(
			"id"	=&gt; $row["id"],
			"first"	=&gt; $row["firstName"],
			"last"	=&gt; $row["lastName"],
			"email"	=&gt; $row["email"],
			"age"	=&gt; $row["age"],
			"phone"	=&gt; $row["phone"],
			"country"=&gt; $row["country"]
		);
	}
	//step 4
	echo json_encode(array(
		"success" =&gt; true,
		"data"	=&gt; $info
	));
</pre>
<p>En el paso uno se realiza la conexión a la base de datos, recuerda que debes poner las credenciales adecuadas así como la base de datos que usarás, en mi caso es “test”.</p>
<p>En el paso dos, al recibir la información que se manda en el evento “load” del formulario, hacemos  el query que regresa todo lo que contiene el registro con ese “id”, es un query muy sencillo.</p>
<p>En el paso tres se itera el resultset que regresó la consulta, dentro del ciclo creamos un arreglo con la información del contacto.</p>
<p>En el paso cuatro se imprime la información en formato JSON, la respuesta será como el siguiente ejemplo:</p>
<pre name="code" class="javascript">
{"success":true,"data":{"id":"2","first":"Sasha","last":"Cohen","email":"sasha@gmail.com","age":"25","phone":"123 - 456 - 7892","country":"USA"}}
</pre>
<p>Con esto cuando demos clic sobre un registro de la tabla la información de ese contacto será cargada automáticamente en el formulario. Y deberíamos tener algo como la siguiente imagen:</p>
<p><!-- imagen 4 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/11/crud-form-4.png" alt="llenando el formulario" />
<p>Llenando el Formulario</p>
</div>
<p>Ahora sí, la información está lista para poder ser editada, lo que debemos hacer ahora es guardar esa información. Para esto usaremos la función (onUpdate) que fue asignada al botón “actualizar”, esta función nos ayudará a realizar lo antes mencionado.</p>
<pre name="code" class="javascript">
onUpdate : function(){
	if (this.form.getForm().isValid()){ //step 1
		this.form.getForm().submit({  //step 2
			scope	: this,
			success	: function(){
				this.store.load()},
			failure	: function(response){
				console.debug(response);
			}
		});
	}else{
		Ext.Msg.alert("Error","All fieds are requiered");
	}
},
</pre>
<p>En el paso uno verificamos que no se encuentre ningún campo vacío del formulario, de lo contrario se manda un mensaje de error.</p>
<p>En el paso dos se hace un “submit” al formulario, con el atributo “scope” indicamos el contexto donde se ejecutarán las funciones definidas en “success” y “failure”.</p>
<p>En la función definida para “success” lo único que hacemos es cargar el store con el propósito de actualizar la tabla con los cambios realizados a la información del contacto.</p>
<p>En la función “failure” solo se imprime en consola la información para ver donde se originó el problema.</p>
<p>Lo que debemos hacer ahora es crear el script PHP que va a actualizar la información en la base de datos, si recordamos en el formulario en el atributo “url” tenemos el archivo “serverside/updateContact.php”, este archivo se encarga de actualizar la base de datos.</p>
<pre name="code" class="php">
&lt;?php	//step 1
	$connection=mysql_connect("localhost","root","") or die("Connection Failed".mysql_error());
	mysql_select_db("test",$connection)or die("Error loading the DataBase".mysql_error());

	//step 2
	$name	= htmlentities($_POST["first"], ENT_QUOTES);
	$last	= htmlentities($_POST["last"], ENT_QUOTES);
	$mail	= htmlentities($_POST["email"], ENT_QUOTES);
	$age	= htmlentities($_POST["age"], ENT_QUOTES);
	$phone	= htmlentities($_POST["phone"], ENT_QUOTES);
	$country	= htmlentities($_POST["country"], ENT_QUOTES);
	$id	= $_POST["id"];

	//step 3
	$query = sprintf("UPDATE  contacts SET email = '%s', firstName = '%s', lastName = '%s', age = '%s' ,phone = '%s', country = '%s' WHERE id=%d",
		mysql_real_escape_string($mail),
		mysql_real_escape_string($name),
		mysql_real_escape_string($last),
		mysql_real_escape_string($age),
		mysql_real_escape_string($phone),
		mysql_real_escape_string($country),
		mysql_real_escape_string($id));

	$rs  = mysql_query($query);

	//step 4
	echo json_encode(array(
		"success" 	=&gt; mysql_errno() == 0,
		"msg"		=&gt; mysql_errno() == 0?"Contact inserted successfully":mysql_error()
	));
</pre>
<p>En el paso uno se realiza la conexión a la base de datos, recuerda que debes poner las credenciales adecuadas así como la base de datos que usarás, en mi caso es “test”.</p>
<p>En el paso dos lo que hacemos es obtener la información mandada por el submit, notemos que la información está siendo pasada por la función PHP “htmlentities” que elimina las etiquetas html en la información que fue introducida. Lo que esta función hacer es convertir la siguiente etiqueta html &lt;b>Luiz&lt;/b> a algo como lo siguiente &lt;b&gt;Luiz&lt;/b&gt; </p>
<p>En el paso tres hacemos un “update” a la tabla en la que están guardados nuestros contactos y le damos como valores la información que fue mandada por el “Store”.</p>
<p>En el paso cuatro 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. </p>
<p>Hasta este momento ya cumplimos con dos de las cuatro funciones de un CRUD leer y actualizar.</p>
<h3>Crear un Registro Nuevo</h3>
<p>En la sección anterior logramos guardar los registros que fueron modificados por el usuario, ahora vamos a insertar nuevos registros en el Grid, para esto usaremos la función (addContact) que fue asignada al botón “crear” esta función nos ayudara a realizar lo antes mencionado.</p>
<pre name="code" class="javascript">
addContact : function(){
	if (this.form.getForm().isValid()){  //step 1
		var contact = new this.store.recordType({  //step 2
			first	: this.form.getForm().getValues().first,
			last	: this.form.getForm().getValues().last,
			email	: this.form.getForm().getValues().email,
			country	: this.form.getForm().getValues().country,
			phone	: this.form.getForm().getValues().phone,
			age	: this.form.getForm().getValues().age
		});
		this.store.insert(0,contact);  //step 3
	}else{
		Ext.Msg.alert("Error","All fields are requiered");
	}
}
</pre>
<p>Creamos la función dentro del objeto principal y en el paso uno verificamos que no se encuentren campos vacios en el formulario, de lo contrario se manda un mensaje de error.</p>
<p>En el paso dos hacemos un registro nuevo asignándole en los campos del Grid la información que el usuario introduce en el formulario para este nuevo registro.</p>
<p>En el paso tres insertamos el contacto nuevo para amostrarlo en el Grid, al tener un “Writer” configurado automáticamente se realizará una petición al servidor con la información a grabar.</p>
<p>Lo siguiente que debemos hacer es guardar ese contacto nuevo en la base de datos. Para esto necesitamos crear el archivo “serverside/createContact.php”, el cual se encargará de introducir el nuevo registro a la base de datos.</p>
<pre name="code" class="php">
&lt;?php	//step 1
	$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["data"];

	$data = json_decode(stripslashes($info));  //step 2

	//step 3
	$name	= htmlentities($data-&gt;first, ENT_QUOTES);
	$last	= htmlentities($data-&gt;last, ENT_QUOTES);
	$email	= htmlentities($data-&gt;email, ENT_QUOTES);
	$age	= htmlentities($data-&gt;age,ENT_QUOTES);
	$phone	= htmlentities($data-&gt;phone, ENT_QUOTES);
	$country= htmlentities($data-&gt;country, ENT_QUOTES);

	//step 4
$query = sprintf("INSERT INTO contacts (email,firstName,lastName,age,phone,country) values ('%s','%s','%s','%s','%s','%s')",
			mysql_real_escape_string($email),
			mysql_real_escape_string($name),
			mysql_real_escape_string($last),
			mysql_real_escape_string($age),
			mysql_real_escape_string($phone),
			mysql_real_escape_string($country));

	$rs = mysql_query($query);

	//step 5
	echo json_encode(array(
		"success" 	=&gt; mysql_errno() == 0,
		"msg"		=&gt; mysql_errno() == 0?"Contact inserted successfully":mysql_error(),
		"data"		=&gt; array(
			array(
				"id"	=&gt; mysql_insert_id(),
				"first"	=&gt; $name,
				"last"	=&gt; $last,
				"email"	=&gt; $email,
				"age"	=&gt; $age,
				"phone"	=&gt; $phone,
				"country"=&gt;$country
			)
		)
	));
</pre>
<p>En el paso uno se realiza la conexión a la base de datos.</p>
<p>En el paso dos, una vez que recibimos la información que mando el “Store” lo decodificamos con la función json_decode() de PHP con esto ya podemos acceder a la información que fue editada en el formulario, la función “stripslashes” elimina el carácter “\” que Apache le agrega, es posible que la configuración de tu servidor no lo haga, pero es bueno prevenir esto para evitarnos errores en el futuro.</p>
<p>En el paso tres revisamos que la información que recibimos del formulario no tenga etiquetas HTML  con la función php htmlentities().</p>
<p>En el paso cuatro hacemos un “insert” y damos como valores la información que fue mandada por el formulario.</p>
<p>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.</p>
<p>Es muy importante mencionar que el Json_encode se está haciendo después del “success” y el “msg” mandamos la información que fue insertada a la base de datos, es muy importante mandar el “id” del nuevo registro, esto nos permitirá que los métodos update y delete funcionen correctamente, si no lo hacemos no funcionarán.</p>
<p>Con esto ya podremos insertar un nuevo registro en nuestro “Grid” y en nuestra base de datos.</p>
<h3>Eliminando un Registro</h3>
<p>En estos momentos solo hemos hecho lo necesario para poder leer los registros y desplegarlos en nuestro “Grid”, podemos añadir nuevo registros y editar los registros existentes por medio de nuestro formulario. Lo único que nos hace falta es eliminar registros y con esto tendríamos las cuatro funciones del CRUD.</p>
<p>Para esto crearemos la función a la que hace referencia el botón “eliminar”, lo que haremos es lo siguiente:</p>
<pre name="code" class="javascript">
onDelete : function(){  //step 1
	var rows = this.grid.getSelectionModel().getSelections();  //step 2
	if(rows.length === 0){  //step 3
		return false;
	}
	this.store.remove(rows);  //step 4
},
</pre>
<p>En el paso uno creamos la función “onDelete” dentro del objeto principal.</p>
<p>En el paso dos tomamos la instancia del “SelectionModel()” de nuestro “Grid”, con esto podemos obtener la información de las filas seleccionadas por el usuario mediante el método “getSelections()”.<br />
En el paso tres lo que hacemos es verificar que el usuario haya seleccionado algo, si no hay nada seleccionado o la selección del “Grid” está vacía no se eliminará ningún registro ya que hacemos un return.</p>
<p>En el paso cuatro ya que se verificó que es un registro que puede ser borrado y lo eliminamos del “Grid” usando el método “remove” del store que contiene los records.</p>
<p>Lo siguiente que debemos hacer es crear el archivo(serverside/destroyContact.php”) que se encargará de borrar el registro de la base de datos.</p>
<pre name="code" class="php">
&lt;?php	//step 1
	$connection=mysql_connect("localhost","root","") or die("Connection Failed".mysql_error());
	mysql_select_db("test",$connection)or die("Error loading the DataBase".mysql_error());

	$id = json_decode(stripslashes($_POST["data"])); //step 2

	//step 3
	$query = sprintf("DELETE FROM contacts WHERE id = %d",
		mysql_real_escape_string($id));

	$rs  = mysql_query($query);

	//step 4
	echo json_encode(array(
		"success" 	=&gt; mysql_errno() == 0,
		"msg"		=&gt; mysql_errno() == 0?"Contact deleted successfully":mysql_error()
	));
</pre>
<p>En el paso uno lo que hacemos es crear la conexión a la base de datos.</p>
<p>En el paso dos obtenemos la información que nos fue mandada, la decodificamos con Json_decode() y la guardamos en la variable “id”. En este caso solo se nos envió el “id” del registro que se quiere eliminar.</p>
<p>En el paso tres solo hacemos el query para eliminar el registro.</p>
<p>En el paso cuatro mandamos como respuesta un mensaje de éxito y si ocurrió un error se manda el error como respuesta.</p>
<p>Si intentamos eliminar un registro notaremos que esta vez también fue borrado de nuestra base de datos. Esta sería la respuesta del servidor:</p>
<pre name="code" class="javascript">
{"success":true,"msg":"Contact deleted successfully"}
</pre>
<p>Con esto terminamos la última parte de nuestro CRUD que es eliminar un registro.</p>
<h3>Conclusión</h3>
<p>En esta ocasión vimos como podemos integrar un formulario y una tabla para poder realizar algunos cambios a la información que esta contiene, con esto podemos crear una nueva aplicación de una manera más dinámica.</p>
<p>Si tienes algún comentario o sugerencia no dudes en comunicarnolos viá el formulario inferior, por el <a href="http://foro.quizzpot.com/">foro</a> o en alguna de las redes sociales como <a href="http://twitter.com/quizzpot">Twitter</a> y <a href="http://www.facebook.com/pages/Quizzpot/299875756793?v=wall">Facebook</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.quizzpot.com/2010/11/integracion-del-formpanel-y-el-gridpanel/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Campos Compuestos</title>
		<link>http://www.quizzpot.com/2010/11/campos-compuestos/</link>
		<comments>http://www.quizzpot.com/2010/11/campos-compuestos/#comments</comments>
		<pubDate>Tue, 02 Nov 2010 15:00:05 +0000</pubDate>
		<dc:creator>Victor Felipe</dc:creator>
				<category><![CDATA[Español]]></category>
		<category><![CDATA[Ext3]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.quizzpot.com/?p=2782</guid>
		<description><![CDATA[En el tutorial de hoy se explica cómo se puede crear más de un campo editable en una sola fila, esto es un caso muy típico cuando capturamos campos como un teléfono, una tarjeta de crédito, etc. ]]></description>
			<content:encoded><![CDATA[<p>Por medio del componente “CompositeField” podemos separar la información de un campo en varios textfields en una misma fila, esto nos ayuda a mejorar la interfaz de nuestra aplicación.</p>
<p>Esta es una muestra de lo que se obtendrá al final de este tutorial. Recuerda que puedes descargar el código fuente si es necesario.</p>
<p><!-- imagen 1 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/11/compo-form-1.png" alt="resultado final" />
<p>Resultado Final</p>
</div>
<h3>La base de datos</h3>
<p>Para este ejemplo usaremos una base de datos solo para guardar los nuevos registros que se creen. La base de datos solo contiene una tabla llamada “friends” que es donde se guardará la información. Actualmente se encuentra vacía.</p>
<pre name="code" class="sql">
-- phpMyAdmin SQL Dump
-- version 3.2.0.1
-- http://www.phpmyadmin.net
--
-- Servidor: localhost
-- Tiempo de generación: 20-10-2010 a las 23:14:21
-- 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 `friends`
--
CREATE TABLE IF NOT EXISTS `friends` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `lastname` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `email` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `phoneNumber` varchar(30) COLLATE utf8_unicode_ci 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 `friends`
--
</pre>
<p>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.</p>
<h3>Empaquetando el tutorial</h3>
<p>Vamos a encapsular el código para evitar conflictos con otras variables. Esto es algo muy importante y siempre lo debemos realizar.</p>
<pre name="code" class="javascript">
Ext.ns("com.quizzpot.tutorials");

com.quizzpot.tutorials.compositeForm ={
	init : function(){
		//code...
	}
}
Ext.onReady(com.quizzpot.tutorials.compositeForm.init,com.quizzpot.tutorials.compositeForm);
</pre>
<p>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.</p>
<h3>Creando el formulario</h3>
<p>Necesitamos un formulario por el cual se obtendrá la información de algún contacto del usuario. Lo primero que haremos es crear este formulario el cual contiene cuatro campos: nombre, apellido, correo electrónico y teléfono. Lo haremos de la siguiente manera:</p>
<pre name="code" class="javascript">
this.form = new Ext.FormPanel({  step 1
	url		     : 'submit.php',  //step 2
	bodyStyle	: "padding : 10px",
	border		: false,
	defaults	: {anchor: "100%", allowBlank: false},
	items		: [ //step 3
			{xtype : "textfield", name : "first", fieldLabel : "Name", labelWidth : 20},
			{xtype : "textfield", name : "last", fieldLabel : "Lastname"},
			{xtype : "textfield", name : "email", fieldLabel : "E-mail",vtype : "email"},
			this.compositeFields ()],
});
</pre>
<p>En el paso uno creamos el formulario, esto es algo que ya hemos visto en tutoriales anteriores.</p>
<p>En el paso dos se le pasa el parámetro “url” donde se realizará el submit del formulario con la información capturada.</p>
<p>En el paso tres creamos los “textfield” de manera “lazy” por medio de su “xtype”, estos los usaremos para obtener la información que nos dará el usuario. Los primeros tres campos los creamos como lo hemos hecho siempre, notemos que el tercer campo cuenta con un “vtype&#8221;, esto lo hacemos con la intención de verificar que el campo tenga la estructura básica de un correo electrónico.</p>
<p>Si notamos al final del arreglo de “items” tenemos la función “compositeFields” la cual veremos en unos momentos. Así que la podemos comentar por el momento.</p>
<p>Ya que tenemos nuestro formulario lo siguiente es crear la ventana donde lo mostraremos al usuario, lo haremos de la siguiente manera:</p>
<pre name="code" class="javascript">
var win = new Ext.Window({
	title	: "Composite Form",
	layout	: "fit",
	width	: 400,
	height	: 200,
	items	: this.form,
   fbar	: [{text: "Save"}]

});
win.show();
</pre>
<p>La creación de una ventana ya es algo que se ha tratado en temas anteriores, por lo cual no entraremos en detalles. Pero si haremos notar que se le está colocando el formulario en el atributo “ítems”, también estamos creando un “fbar” que contiene el botón “Save”. Con esto tendríamos algo como lo que se muestra a continuación:</p>
<p><!-- imagen 2 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/11/compo-form-2.png" alt="colocando el formulario" />
<p>Colocando el Formulario</p>
</div>
<h3>Función compositeFields</h3>
<p>En esta función veremos cómo implementar los “CompositeField”, lo que esto nos permite es tener una cierta cantidad de campos de texto en una sola fila. Esto es posible a partir de la versión 3.X de Ext JS, a continuación veremos la implementación de esto.</p>
<pre name="code" class="javascript">
compositeFields : function(){  //step 1
return{
		xtype	        : "compositefield", //step 2
		fieldLabel	: "Phone",
		defaults	: {allowBlank: false},
		border	      : false,
		items	        : [ {xtype : "displayfield", value:"("},  //step 3
			{xtype : "textfield", name : "phoneNum1", width: 30},  //step 4
			{xtype : "displayfield", value:") - "},
			{xtype : "textfield", name : "phoneNum2", width: 50},
			{xtype : "displayfield", value:" - "},
			{xtype : "textfield", name : "phoneNum3", width: 50}
				]
	};
},
</pre>
<p>En el paso uno creamos la función.</p>
<p>En el paso dos creamos el componente “compositefield” por medio de su “xtype”, es importante mencionar que esto también se puede hacer realizando una instancia de “Ext.form.CompositeField” con el operador “new”. </p>
<p>En el paso tres usamos un “displayfield” para mostrar algo de texto antes del “textfield”.</p>
<p>Del paso cuatro en adelante se crean los “textfield” que se usarán para recibir la información del usuario. Notemos que entre cada “textfield” hay un “displayfield” esto es con el objetivo de dotar de mayor usabilidad al formulario.</p>
<p>Con esto tendríamos algo como lo siguiente:</p>
<p><!-- imagen 3 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/11/compo-form-3.png" alt="completando el formulario" />
<p>Completando el Formulario</p>
</div>
<p>Como podemos notar al usar un “CompositeField” podemos tener varios “textfields” en una sola fila, a diferencia de como siempre lo hemos hecho, colocándolos en diferentes filas.</p>
<h3>Enviando la información</h3>
<p>Ya que tenemos nuestro formulario listo, lo siguiente es guardar la información en la base de datos, lo primero que haremos será agregar un handler al botón “Save”, de esta manera podemos agregarle acciones para cuando el usuario de clic sobre este.</p>
<pre name="code" class="javascript">
var win = new Ext.Window({
	title	: "Composite Form",
	layout	: "fit",
	width	: 400,
	height	: 200,
	items	: this.form,
	fbar	: [{text: "Save",handler:this.onSave,scope:this}]  //step 1

});
win.show();
</pre>
<p>En el paso uno agregamos el “handler” al botón, esta función se dispara cada vez que se da clic sobre el botón. En este ejemplo el “handler” tiene definida la función “onSave” la cual se encarga de hacer la petición Ajax al servidor enviando la información introducida por el usuario.</p>
<pre name="code" class="javascript">
onSave :function(){

	this.form.getForm().submit({
		scope	: this,
		success	: this.showResults,
		failure	: function(response){
			console.debug(response);
			}
	});
},
</pre>
<p>Es importante mencionar que en el atributo “success” se emplea otra función que es showResults, lo que hace esta función es simplemente mandar un mensaje de alerta informándonos que todo salió bien, aquí también usamos la configuración “scope”, esto permite definir el contexto donde se ejecutará la función asignada al callback “success” y “failure”.</p>
<h3>Guardado la información</h3>
<p>En los pasos anteriores realizamos el “submit” al formulario una vez que el usuario da clic sobre el botón “Save”, ahora vamos a guardar la información en la base de datos. En el archivo “submit.php” escribimos el siguiente código:</p>
<pre name="code" class="php">
&lt;?php	//sptep 1
	$connection=mysql_connect("localhost","root","") or die("Connection Failed".mysql_error());
	mysql_select_db("test",$connection)or die("Error loading the DataBase".mysql_error());

	//step 2
	$name = $_POST["first"];
	$last = $_POST["last"];
	$email = $_POST["email"];
	$phone1 = $_POST["phoneNum1"];
	$phone2 = $_POST['phoneNum2'];
	$phone3 = $_POST['phoneNum3'];
	//step 3
	$phone = $phone1.'-'.$phone2.'-'.$phone3;

	//Se recomienda limpiar aquí las variables de entrada antes de guardarlas en a base de datos!!

	//step 4
	$query = sprintf("INSERT INTO friends(name,lastname,email,phoneNumber) values('%s','%s','%s','%s')",
		mysql_real_escape_string($name),
		mysql_real_escape_string($last),
		mysql_real_escape_string($email),
		mysql_real_escape_string($phone));

	$rs = mysql_query($query);

	echo json_encode(array(
		"success"	=&gt; true
	));
</pre>
<p>En el paso uno se realiza la conexión a la base de datos, recuerda que debes poner las credenciales adecuadas así como la base de datos que usarás, en mi caso es “test”.</p>
<p>En el paso dos recibimos vía POST la información introducida por el usuario, esta información fue enviada automáticamente al hacer “submit” al formulario que definimos en ExtJS.</p>
<p>En el paso tres lo que hacemos es concatenar las tres partes del número telefónico, para que sea guardado como una sala cadena de caracteres.</p>
<p>En el paso cuatro introducimos la información a la tabla “friends”.</p>
<p>Es importante mencionar que se deben limpiar las variables antes de insertarlas a la base de datos, esto para evitar ataques XSS, existen liberías que te permiten realizar la limpieza de una manera sencilla.</p>
<h3>Mensaje de éxito</h3>
<p>Una vez que se ha guardado el nuevo contacto crearemos la función “showResult” que es el callback para cuando la comunicación ha sido satisfactoria, dentro de esta función solamente mandaremos un mensaje indicándole al usuario que su información ha sido guardada.</p>
<pre name="code" class="javascript">
showResults	: function(response){
		Ext.Msg.alert("Alert"," Information has been saved!");
	}
</pre>
<p><!-- imagen 4 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/11/compo-form-4.png" alt="mensaje de exito" />
<p>Mensaje de Éxito </p>
</div>
<h3>Conclusión</h3>
<p>En este tutorial vimos un uso básico del “CompositeField”, este componte nos ayuda a tener más de un “textfield” en la misma fila, esto es conveniente cuando queremos tener una cadena de caracteres dividida en varios campos editables, como el número telefónico en este ejemplo.</p>
<p>Si tienes algún comentario o sugerencia no dudes en comunicarnolos viá el formulario inferior, por el <a href="http://foro.quizzpot.com/">foro</a> o en alguna de las redes sociales como <a href="http://twitter.com/quizzpot">Twitter</a> y <a href="http://www.facebook.com/pages/Quizzpot/299875756793?v=wall">Facebook</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.quizzpot.com/2010/11/campos-compuestos/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Grid con columnas dinámicas</title>
		<link>http://www.quizzpot.com/2010/10/grid-con-columnas-dinamicas/</link>
		<comments>http://www.quizzpot.com/2010/10/grid-con-columnas-dinamicas/#comments</comments>
		<pubDate>Thu, 28 Oct 2010 14:01:56 +0000</pubDate>
		<dc:creator>Victor Felipe</dc:creator>
				<category><![CDATA[Español]]></category>
		<category><![CDATA[Ext3]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.quizzpot.com/?p=2759</guid>
		<description><![CDATA[En esta ocasión veremos cómo podemos hacer nuestros “Grids” un poco más dinámicos, esto lo haremos al cargar todo la información desde nuestra base de datos, incluyendo la información necesaria para los “headers” del “Grid”.]]></description>
			<content:encoded><![CDATA[<p>En este tutorial veremos cómo podemos cargar dinámicamente la propiedad “header” de un “Grid”, con la finalidad de hacer nuestro código de una manera más eficiente y dinámico dando posibilidad de poder definir las columnas de manera dinámica.</p>
<p>Esta es una muestra de lo que se obtendrá al final de este tutorial. Recuerda que puedes descargar el código fuente si es necesario.</p>
<p><!-- imagen 1 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/10/grid-col-dimanicas-1.png" alt="resultado final" />
<p>Resultado Final</p>
</div>
<h3>La base de datos</h3>
<p>En esta ocasión la información que usaremos está en una tabla llamada “grid” la cual contiene la información necesaria para cumplir con nuestro objetivo final. El código para generar esta tabla se muestra a continuación:</p>
<pre name="code" class="sql">
-- phpMyAdmin SQL Dump
-- version 3.2.0.1
-- http://www.phpmyadmin.net
-- Servidor: localhost
-- Tiempo de generación: 24-10-2010 a las 06:19:17
-- 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 `grids`
CREATE TABLE IF NOT EXISTS `grids` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `Name` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `Lastname` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `Age` int(3) NOT NULL,
  `Nationality` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `Sex` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `ZipCode` varchar(15) COLLATE utf8_unicode_ci NOT NULL,
  `Address` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=2 ;
--
-- Volcar la base de datos para la tabla `grids`
--

INSERT INTO `grids` (`id`, `Name`, `Lastname`, `Age`, `Sex`, `ZipCode`, `Address`) VALUES
(1, 'John', 'Smith', 20, 'Male', '50300', 'at home'),
(2, 'Nicole', 'Summer', 22, 'Female', '55687', 'somewhere');
</pre>
<p>La base de datos la he llamado “test”, pero puedes usar el nombre que gustes, solamente cuando se haga la conexión mediante PHP recuerda ponerle el nombre correcto.</p>
<h3>Exponer la información</h3>
<p>Como sabemos la información es una parte muy importante en una aplicación, en esta ocasión obtendremos esta información desde nuestra base de datos, por lo cual tenemos que hacer la conexión via PHP y un query para poder obtenerla.</p>
<pre name="code" class="php">
&lt;?php	//step 1
	$connection= mysql_connect("localhost","root","") or die("Connection Failed".mysql_error());
	mysql_select_db("test",$connection)or die("Error loading the DataBase".mysql_error());
	//step 2
	$result= mysql_query("SELECT * FROM grids");

	$data = array();
	//step 3
	while($row = mysql_fetch_array($result)){
		array_push($data, array(
			"id" 		=&gt; $row["id"],
			"name" 		=&gt; $row["Name"],
			"lastname"	=&gt; $row["Lastname"],
			"age" 		=&gt; $row["Age"],
			"sex"		=&gt; $row["Sex"],
			"zip" 		=&gt; $row["ZipCode"],
			"address" 	=&gt; $row["Address"],
		));
	}
	//step 4
	$fields=array(
		array("name" =&gt; "id"),
		array("name" =&gt; "name","header"	=&gt;"Name"),
		array("name" =&gt; "lastname","header"	=&gt;"Lastname"),
		array("name" =&gt; "age","header"	=&gt;"Age"),
		array("name" =&gt; "sex","header"	=&gt;"Sex"),
		array("name" =&gt; "zip","header"	=&gt;"ZipCode"),
		array("name" =&gt; "address","header"	=&gt;"Address"),
	);
	//step 5
	$metadata = array(
		"totalProperty"	=&gt; "results",
		"successProperty"	=&gt; "success",
		"idProperty"	=&gt; "id",
		"fields"		=&gt; $fields,
		"root"		=&gt; "data"
	);
	//step 6
	echo json_encode(
		array(
		"success"	=&gt; true,
		"metaData"	=&gt; $metadata,
		"data"		=&gt; $data
	));
</pre>
<p>En el paso uno se realiza la conexión a la base de datos, recuerda que debes poner las credenciales adecuadas así como la base de datos que usarás, en mi caso es “test”.</p>
<p>En el paso dos se crea el query que regresa toda la información de la tabla “grids”.</p>
<p>En el paso tres se itera el resultset que regresó la consulta, dentro del ciclo creamos un arreglo con la información que<br />
contiene la tabla.</p>
<p>Hasta este momento la estructura del documento es conocida, lo interesante viene en el paso cuatro.</p>
<p>En el paso cuatro se crea un nuevo arreglo llamado “fields”, este arreglo lo que contiene son los nombres de los campos que conforman nuestra tabla “grids”.</p>
<p>En el paso cinco se crea el arreglo.</p>
<p>En el paso seis imprimimos la información en formato Json, la respuesta será semejante al siguiente ejemplo:</p>
<pre name="code" class="javascript">
{"success":true,"metaData":{"totalProperty":"results","successProperty":"success","idProperty":"id","fields":[{"name":"id"},{"name":"name","header":"Name"},{"name":"lastname","header":"Lastname"},{"name":"age","header":"Age"},{"name":"sex","header":"Sex"},{"name":"zip","header":"ZipCode"},{"name":"address","header":"Address"}],"root":"data"},"data":[{"id":"1","name":"John","lastname":"Smith","age":"20","sex":"Male","zip":"50300","address":"at home"}]}
</pre>
<h3>Encapsulando el código</h3>
<p>Ahora pasamos a la parte de JavaScript donde en primer lugar es necesario encapsular el código para evitar problemas en el futuro, así que crearemos un objeto donde alojaremos el código del tutorial.</p>
<pre name="code" class="javascript">
Ext.ns("com.quizzpot.tutorial");
com.quizzpot.tutorial.Grid= {

       init :  function(){
        //initial code goes here
        }
}
Ext.onReady(com.quizzpot.tutorial.grid.init,com.quizzpot.tutorial. Grid);
</pre>
<p>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.</p>
<h3>Solicitando la información al servidor</h3>
<p>Lo que haremos a continuación es solicitar la información al servidor para poder mostrarla, ya dentro de la función “init” haremos lo siguiente: </p>
<pre name="code" class="javascript">
	//step 1
	this.store = new Ext.data.JsonStore({
		url : "grid.php"
	});
	//step 2
	this.store.on("load",this.createGrid,this);
	this.store.on("loadexception",this.error,this);
	this.store.load();
	},
</pre>
<p>En el paso uno lo que hacemos es crear el “JsonStore” con el cual solicitamos la información al servidor, lo interesante de esto es que el “JsonStore” no recibe ningún parámetro más que  “url”, esto es porque si recordamos en el archivo PHP que creamos hace unos instantes contiene los demás parámetros para el “store”.</p>
<p>En el paso dos antes de hacer la petición al servidor tenemos dos eventos “load” y “loadexception”, el primer evento se lleva a cabo cuando el “store” hará la petición al servidor y el segundo será ejecutado si es que algo sale mal mientras el “store” es cargado.</p>
<p>Ambos tienen una función que se encarga de hacer lo necesario para cada uno de estos eventos.</p>
<h3>Función “createGrid”</h3>
<p>La  función del evento “load” lo que hace es crear el “Grid” con la información que el servidor regresó, esto lo haremos de la siguiente manera:</p>
<pre name="code" class="javascript">
createGrid : function(Store,records,options,groups){
	var cm = []; //step 1

	Ext.each(this.store.fields.items,function(data){ //step 2
		if(data.name !== "id"){
			cm.push({header:data.header,dataIndex:data.name,sortable:true}); //step 3
		}
});
//…. Seguiremos escribiendo aquí
}
</pre>
<p>Creamos la función “createGrid” como normalmente lo hacemos, solo que en esta ocasión le pasamos como parámetros lo que nos regresa el evento “load”.</p>
<p>En el paso uno creamos un arreglo llamado “cm”, el cual lo usaremos para colocar dinámicamente los “headers” de las columnas para nuestro “Grid”.</p>
<p>En el paso dos iteramos la respuesta del servidor, comprobamos en cada iteración que el siguiente campo en la respuesta no sea un “id”. Puedes ver que al arreglo “cm” se le insertan los parámetros necesarios para formar el “header” de una columna, ya que este parámetro le asignamos “data.header” y a “dataIndex” le asignamos “data.name” recordando que esta información está especificada dentro de nuestro archivo PHP.</p>
<p>Con esto tenemos la información necesaria para formar las cabeceras de las columnas del “Grid”, lo siguiente es crearlo y desplegarlo.</p>
<pre name="code" class="javascript">
this.grid = new Ext.grid.GridPanel({  //step 1
store 		: this.store,
	columns 	: cm,
	border		: false,
	stripeRows	: true
});

this.win = new Ext.Window({  //step 2
	title 	: "Colums",
	layout	: "fit",
	width	: 500,
	height	: 300,
	items	: this.grid
});
this.win.show();
</pre>
<p>En el paso uno creamos el “Grid”, éste paso ya debería ser conocido para nosotros, pero como pudiste observar generalmente en el atributo “columns” colocamos todas las cabeceras de nuestras columnas, pero en esta ocasión le pasamos el arreglo “cm” que creamos y llenamos anteriormente. </p>
<p>En el paso dos se crea la ventana en la cual mostraremos nuestro “Grid”.</p>
<p><!-- imagen 1 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/10/grid-col-dimanicas-2.png" alt="colocando el gridl" />
<p>Colocando el Grid</p>
</div>
<h3>Función “error”</h3>
<p>Esta es la función del evento “loadexception”, lo único que haré en esta función es mandar la información que se generó, con el fin de poder buscar donde está el error y el porqué no se puede mostrar nuestra información.</p>
<p>Esta función tiene la siguiente estructura:</p>
<pre name="code" class="javascript">
error :function(){
console.debug(arguments)
}
</pre>
<p>Como mencionamos hace uno instantes lo único que hace esta función es mandar a consola la información por la cual se pudo originar el error.</p>
<h3>Conclusión</h3>
<p>En esta ocasión vimos que podemos crear las cabeceras de nuestro “Grid” de una manera más dinámica, esto resulta efectivo en grandes proyectos, ya que esto nos ayuda a simplificar y automatizar la creación de los “grids”.</p>
<p>Si tienes algún comentario o sugerencia no dudes en comunicarnolos viá el formulario inferior, por el <a href="http://foro.quizzpot.com/">foro</a> o en alguna de las redes sociales como <a href="http://twitter.com/quizzpot">Twitter</a> y <a href="http://www.facebook.com/pages/Quizzpot/299875756793?v=wall">Facebook</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.quizzpot.com/2010/10/grid-con-columnas-dinamicas/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>CRUD de un catálogo de contactos</title>
		<link>http://www.quizzpot.com/2010/10/crud-de-un-catalogo-de-contactos/</link>
		<comments>http://www.quizzpot.com/2010/10/crud-de-un-catalogo-de-contactos/#comments</comments>
		<pubDate>Thu, 21 Oct 2010 14:00:35 +0000</pubDate>
		<dc:creator>Victor Felipe</dc:creator>
				<category><![CDATA[Español]]></category>
		<category><![CDATA[Ext3]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.quizzpot.com/?p=2705</guid>
		<description><![CDATA[En esta ocasión vamos a Crear, Leer, Actualizar y Borrar (CRUD) un catálogo de contactos usando un EditorGrid que a su vez contendrá un Writter en su Store. Con esto podremos simplificar nuestro código al momento de hacer las peticiones a nuestro servidor.]]></description>
			<content:encoded><![CDATA[<p>En este tutorial haremos un CRUD para poder editar la información contenida en un EditorGrid, esto lo lograremos mediante el  Writter de un store.</p>
<p><!-- imagen 1 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/10/crud-1.png" alt="resultado final" />
<p>Resultado Final</p>
</div>
<p>Durante el tutorial se irá explicando el código necesario para realizarlo, recuerda que puedes descargar el código fuente si te es necesario.</p>
<h3>La Base de Datos</h3>
<p>La información para el EditorGrid estará en una base de datos de MySQL que contendrá una tabla llamada “contacts”, en esta tabla solo tenemos la información básica de un contacto. El código para generar la tabla se muestra a continuación.</p>
<pre name="code" class="sql">
-- phpMyAdmin SQL Dump
-- version 3.2.0.1
-- http://www.phpmyadmin.net
--
-- Servidor: localhost
-- Tiempo de generación: 18-10-2010 a las 13:25: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 `contacts`
--

CREATE TABLE IF NOT EXISTS `contacts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `email` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
  `firstName` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `lastName` varchar(39) COLLATE utf8_unicode_ci 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 `contacts`
--

INSERT INTO `contacts` (`id`, `email`, `firstName`, `lastName`) VALUES
(1, 'pedro@gmail.com', 'Pedro', 'Lopez'),
(2, 'jose@hotmail.com', 'Jose', 'Paz'),
(3, 'john@hotmail.com', 'John', 'Smith');
</pre>
<p>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.</p>
<h3>Exponer la Información </h3>
<p>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” de la siguiente manera. El siguiente código se debe escribir en un archivo llamado “serverside/getContacts.php”.</p>
<pre name="code" class="php">
&lt;?php
	//step 1
	$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 contacts");  //step 2

	$data= array();
	while($row= mysql_fetch_array($result)){  //step 3
		array_push($data,array(
			"id"	=&gt; $row["id"],
			"first"	=&gt; $row["firstName"],
			"last"	=&gt; $row["lastName"],
			"email"	=&gt; $row["email"],
		));
	}
	echo json_encode(  //step 4
		array(
		"success"	=&gt; true,
		"data"		=&gt; $data
	));
</pre>
<p>En el paso uno se realiza la conexión a la base de datos, recuerda que debes poner las credenciales adecuadas así como la base de datos que usarás, en mi caso es “test”.</p>
<p>En el paso dos se hace el query que regresa todo lo que contiene la tabla “contacts”, es un query muy sencillo.</p>
<p>En el paso tres se itera el resultset que regresó la consulta, dentro del ciclo creamos un arreglo con la información de cada uno de los contactos.</p>
<p>En el paso cuatro se imprime la información en formato JSON, la respuesta será como el siguiente ejemplo:</p>
<pre name="code" class="javascript">
{"success":true,"data":[{"id":"1","first":"Pedro","last":"Lopez","email":"pedro@gmail.com"},{"id":"2","first":"Jose","last":"Paz","email":"jose@hotmail.com"}}
</pre>
<p>Con eso es suficiente para poder generar mediante JavaScript la interface del  Grid ya que tenemos toda la información necesaria.</p>
<h3>Empaquetando el Tutorial</h3>
<p>Vamos a empaquetar el código para evitar conflictos con otras variables. Esto es algo muy importante y siempre lo debemos realizar.</p>
<pre name="code" class="javascript">
Ext.ns("com.quizzpot.tutorials");

com.quizzpot.tutorials.Crud = {
	init : function() {
		//code
	}
}
Ext.onReady(com.quizzpot.tutorials.Crud.init,com.quizzpot.tutorials.Crud);
</pre>
<p>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.</p>
<h3>Creado el CRUD</h3>
<p>Lo que haremos a continuación es solicitar la información al servidor, esto será ya dentro de la función “init” de nuestro archivo “crudexample.js”. Como mencionamos anteriormente usaremos un writer que se encargue de hacer las operaciones básicas (leer, escribir, modificar y eliminar). Para lograr esto es necesario definir la propiedad “api” con las URLs donde el “proxy” realizará las peticiones Ajax de manera automática, nótese que no estamos usando la propiedad “url” que normalmente usamos.</p>
<pre name="code" class="javascript">
var proxy = new Ext.data.HttpProxy({  //step 1

	api: {	//step 2
		read 	        : "serverside/getContacts.php",
		create 	: "serverside/createContact.php",
		update	: "serverside/updateContact.php",
		destroy	: "serverside/destroyContact.php"
	}
});
</pre>
<p>En el paso uno se crea una instancia de “Ext.data.HttpProxy” esto es para que el “store” realice las peticiones Ajax de manera automática.</p>
<p>En el paso dos usamos la configuración “api” con las URLs a donde se realizarán las peticiones Ajax para cada acción a realizar. Por el momento solo tenemos definido el archivo “getContacts.php”, los demás los definiremos más adelante.</p>
<p>A continuación haremos el “Reader”  y el “Writer”:</p>
<pre name="code" class="javascript">
var reader = new Ext.data.JsonReader({ //step 1
	totalProperty	: "total",
	successProperty	: "success", // indica la propiedad que define si se ha insertado/actualizado o borrado con éxito
	messageProperty	: "message",
	idProperty		: "id",
	root			: "data" //este es el nombre del parámetro que llega al servidor con el JSON modificado
	},[  //step 2
		{name: "email", allowBlank: false},
		{name: "first", allowBlank: false},
		{name: "last", allowBlank: false}
	]);

var writer = new Ext.data.JsonWriter({ //step 3
		encode		: true,
		writeAllFields	: true//decide si se manda al servidor solamente los campos modificados o todo

});
</pre>
<p>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.</p>
<p>En el paso dos colocamos los campos que conforman el “Record” que contendrá la información que usaremos en el grid.</p>
<p>En el paso tres se crea la instancia del “JsonWriter”, el atributo “encode” lo usamos para poner la información que se escribe en el grid en formato JSON, el atributo “writeAllFields” forza al “writer” a enviar todos los campos del record y no solamente aquellos que se han modificado.</p>
<p>Lo siguiente es hacer el store que tendrá al “JsonReader”, “JsonWriter” y al “HttpProxy”. Lo haremos de la siguiente manera:</p>
<pre name="code" class="javascript">
this.storeGrid = new Ext.data.Store({ //step 1
	id		: "id",
	proxy		: proxy,
	reader		: reader,
	writer		: writer,
	autoSave	: true	//<--hace las peticiones al servidor automáticamente
});

this.storeGrid.load();  //step 2
</pre>
<p>En el paso uno lo que haces es hacer una instancia del store, esto es con el motivo de unir el “reader”, el “writer” y el “proxy”. Notemos que el “JsonWriter” es introducido al store de la misma manera de la que lo hacemos con el “JsonReader”, el store lo creamos como un objeto dentro de la función “init”.</p>
<p>En el paso dos cargamos el store como siempre lo hemos hecho, esto ejecuta una petición Ajax al servidor.</p>
<p>Con esto tenemos lo preparado al store para poder hacer las operaciones del CRUD de manera automática y muy sencilla.</p>
<h3>Creando un Grid Editable</h3>
<p>A continuación crearemos el grid editable, lo primero que haremos es hacer el grid y desplegar la información que traemos desde la base de datos.</p>
<pre name="code" class="javascript">
var textFieldEmail = new Ext.form.TextField({vtype: "email",allowBlank: false}), //step 1
textField = new Ext.form.TextField({allowBlank: false}),
	sm = new Ext.grid.CheckboxSelectionModel();

this.grid = new Ext.grid.EditorGridPanel({ //step  2
	store		: this.storeGrid, //step 3
	columns	: [
			sm,
			{header:'E-mail', dataIndex:'email', sortable: true, width:150, editor:textFieldEmail},
			{header:'Name', dataIndex:'first',sortable: true, editor:textField},
			{header:'Lastname', dataIndex:'last',sortable: true, editor:textField}
			],
	sm		: sm,
	border		: false,
	stripeRows	: true
});
</pre>
<p>En el paso uno creamos lo necesario para poder hacer cambios a nuestra tabla, lo que hicimos fue crear una instancia de “TextField” con un vtype de tipo “email”, esto es con el fin de que cuando se intente hacer un cambio o crear un nuevo contacto se haga un validación de que lo que se introdujo sea una dirección de correo electrónico válida.  Y por ultimo con el “allowBlank” no dejamos que el campo este vacío.</p>
<p>Se crea una segunda instancia de “TextField” pero esta no cuenta con un vtype ya que en esta no se tiene que hacer alguna validación de ese tipo pero si tiene el “allowBlank” para no permitir que este campo este vacío.</p>
<p>Por último creamos un “checkBox” para hacer el selectionModel. El resto del código es conocido para nosotros si no te recomendamos ver los <a href="http://www.quizzpot.com/2009/08/editar-las-celdas-de-un-grid/">tutoriales </a>sobre esto.</p>
<p>En el paso dos creamos la tabla que editaremos.</p>
<p>En el paso tres le pasamos el “storeGrid” que contiene la información a desplegar en el grid.</p>
<p>Por último colocaremos nuestra tabla en una ventana para poder mostrar los registros de esta.</p>
<pre name="code" class="javascript">
var win = new Ext.Window({
	title	: "CRUD Example",
	layout	: "fit",
	tbar	: [
		{text:'New Contact', scope:this, handler:this.addContact,iconCls:'save-icon'},
		{text:"Delete", scope:this, handler:this.onDelete,iconCls:'delete-icon'}],
	width	: 400,
	height	: 300,
	items	: [this.grid]
});
win.show();
</pre>
<p>Creamos la ventana esto ya es conocido para nosotros. Es importante mencionar que se crean los botones de “Nuevo Contacto” y “Eliminar” en la barra de herramienta, es importante mencionar que se les esta colocando una imagen a los botones, para esto es necesario definir las clases CSS (save-icon) y CSS(delete-icon) en nuestra hoja de estilos o documento HTML de la siguiente manera:</p>
<pre name="code" class="css">
.save-icon{background:transparent url(icons/add.png) 0 0 no-repeat !important;}
.delete-icon{background:transparent url(icons/delete.png) 0 0 no-repeat !important;}
</pre>
<p>Por el  momento no trabajaremos con las funciones que están en los botones ya que lo haremos un poco más adelante así que puedes comentar el atributo “handler”. En este momento deberíamos tener algo como lo siguiente imagen:</p>
<p><!-- imagen 2 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/10/crud-2.png" alt="leer los registros" />
<p>Mostrar los contactos</p>
</div>
<p>Al ejecutar nuestra aplicación podemos notar que los campos de la tabla tienen los registros que trajimos de la base de datos.</p>
<h3>Grabar los Registro Modificados</h3>
<p>Hasta este punto tenemos la información en nuestro “Grid” lo siguiente que tenemos que hacer para poder cumplir una de las funciones del CRUD es editar los registros del “Grid” y guárdarlos en la base de datos.</p>
<p>En este momento si editamos un registro no se actualiza en la base de datos, pero si se cambia en el “Grid”. Al intentar hacer esto nos marca el siguiente error:</p>
<pre name="code" class="javascript">
POST serverside/updateContact.php  404 Not Found
</pre>
<p>El error 404 nos indica que la url no existe, así que vamos a crear el archivo “serverside/updateContact.php”, este archivo es el que se conecta a la base de datos para poder actualizar el registro, a continuación veremos la estructura de este archivo.</p>
<pre name="code" class="php">

&lt;?php	//step 1
	$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["data"];

	$data = json_decode(stripslashes($info)); //step 2

	$mail = $data-&gt;email;  //step 3
	$name = $data-&gt;first;
	$last = $data-&gt;last;
	$id   = $data-&gt;id;

	//step 4
	$query = sprintf("UPDATE  contacts SET email = '%s', firstName = '%s', lastName = '%s' WHERE id=%d",
mysql_real_escape_string($mail),
		mysql_real_escape_string($name),
		mysql_real_escape_string($last),
		mysql_real_escape_string($id));

	$rs  = mysql_query($query);

	echo json_encode(array(  //step 5
		"success" 	=&gt; mysql_errno() == 0,
		"msg"		=&gt; mysql_errno() == 0?"Contact inserted successfully":mysql_error()
	));
</pre>
<p>En el paso uno se realiza la conexión a la base de datos, recuerda que debes poner las credenciales adecuadas así como la base de datos que usarás, en mi caso es “test”.</p>
<p>En el paso dos, una vez que recibimos la información que mando el “Store” lo descodificamos 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 no lo haga, pero es bueno prevenir esto apra evitarnos errores en el futuro.</p>
<p>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.<br />
En el paso cuatro hacemos un “update” a la tabla en la que están guardados nuestros contactos y le damos como valores la información que fue mandada por el “Store”.</p>
<p>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.</p>
<p>Con esto si intentamos nuevamente hacer un cambio a  un registro en el “Grid” veremos algo como lo siguiente:</p>
<p><!-- imagen 3 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/10/crud-3.png" alt="actualizar registro" />
<p>Actualizar un contacto</p>
</div>
<p>En este momento ya se guardan los registros en la base de datos y se tiene como respuesta algo como lo siguiente:</p>
<pre name="code" class="javascript">
{"success":true,"msg":"Contact inserted successfully"}
</pre>
<p>Hasta este momento ya cumplimos con dos de las cuatro funciones de un CRUD leer y actualizar si notamos la mayor parte de esto fue manejado por el “proxy”, el “JsonReader” y el “JsonWriter” nosotros solo creamos los archivos php, esto nos fácilita mucho las cosas.</p>
<h3>Crear un registro nuevo</h3>
<p>En la sección anterior logramos guardar los registros que fueron modificados por el usuario, ahora vamos a insertar nuevos registros en el Grid, para esto usaremos la función (addContact) que fue asignada al botón “nuevo contacto” esta función nos ayudara a realizar lo antes mencionado.</p>
<pre name="code" class="javascript">
addContact : function(){
	var contact = new this.storeGrid.recordType({ //step 1
		first	: "",
		last	: "",
		email	: ""
	});
	//step 2
	this.grid.stopEditing();
	this.storeGrid.insert(0,contact);
	this.grid.startEditing(0,1);
}
</pre>
<p>Creamos la función dentro del objeto principal y en el paso uno hacemos un nuevo registro poniendo los campos en del “Grid” vacios para que después el usuario pueda introducir la información necesaria, también podríamos definir valores por defecto.</p>
<p>En el paso dos con “stopEditing” nos aseguramos que el usuario no esté modificando los campos, en el momento que se decida introducir un nuevo contacto. Ya que nos aseguramos que no se están editando, insertamos el nuevo contacto con los campos vacíos, y por último permitimos al usuario editar los campos con “strartEditng(0,1)” notemos que éste recibe como parámetros la posición de la celda donde se inicia a editar donde “0” es el numero de fila y “1” es el número de columna.</p>
<p>Si ejecutamos nuestra aplicación veremos algo semejante a la siguiente imagen:</p>
<p><!-- imagen 4 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/10/crud-4.png" alt="crando  registro" />
<p>Creando un contacto</p>
</div>
<p>Notemos que nos manda el siguiente error:</p>
<pre name="code" class="javascript">
POST serverside/createContact.php  404 Not Found
</pre>
<p>Al igual que en el caso anterior tenemos que crear el archivo “createContact.php” en el cual se hacer la conexión a la base de datos y se guarda el nuevo registro, la estructura del archivo se muestra a continuación:</p>
<pre name="code" class="php">
&lt;?php
	//step 1
	$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["data"];

	$data = json_decode(stripslashes($info)); //step 2

	$name = $data-&gt;first; //step 3
	$last     = $data-&gt;last;
	$email = $data-&gt;email;

	//step 4
	$query = sprintf("INSERT INTO contacts (email,firstName,lastName) values ('%s','%s','%s')",
			mysql_real_escape_string($email),
			mysql_real_escape_string($name),
			mysql_real_escape_string($last));

	$rs = mysql_query($query);

	//step 5
	echo json_encode(array(
		"success" 	=&gt; mysql_errno() == 0,
		"msg"		=&gt; mysql_errno() == 0?"Contact inserted successfully":mysql_error(),
		"data"		=&gt; array(
			array(
				"id"	=&gt; mysql_insert_id(),
				"first"	=&gt; $name,
				"last"	=&gt; $last,
				"email"	=&gt; $email
			)
		)
	));
</pre>
<p>La estructura de este archivo es muy semejante a la de los archivos previos.</p>
<p>En el paso uno lo único que hacemos es hacer la conexión a la base de datos.</p>
<p>En el paso dos decodificamos la información que nos manda el “Store”, esto lo hacemos mediante la función Json_decode() y le pasamos la información la cual es el registro que creó el usuario.</p>
<p>En el paso tres lo que hacemos es sacar esa información y guardarla en unas variables para poder insertar esa información a la tabla “contacts” de nuestra base de datos.</p>
<p>En el paso cuatro creamos el query que insertara los datos a la base de datos, es un query simple un “insert” le damos los campos y los valores que es la información que obtuvimos en el paso tres.</p>
<p>En el paso cinco lo que hacemos es mandar un mensaje y la información que fue insertada al base de datos.</p>
<p>Es muy importante mencionar que en el Json_encode que se está haciendo después del “success” y el “msg” mandamos la información que fue insertada a la base de datos, es muy importante mandar el “id” del nuevo registro, esto nos permitirá que los métodos update y delete funcionen correctamente, si no lo hacemos no funcionarán.</p>
<p>Si intentamos insertar un nuevo registro esta será la respuesta:</p>
<pre name="code" class="javascript">
{"success":true,"msg":"Contact inserted successfully","data":[{"id":4,"first":"Alejando","last":"Cruz","email":"alejandro@gmail.com"}]}
</pre>
<p>Con esto ya podremos insertar un nuevo registro en nuestro “Grid” y en nuestra base de datos.</p>
<h3>Eliminar un registro</h3>
<p>En estos momentos solo hemos hecho lo necesario para poder leer los registros y desplegarlos en nuestro “Grid”, podemos añadir nuevo registros y editar los registros existentes. Lo único que nos hace falta es eliminar registros y con esto tendríamos las cuatro funciones del CRUD.</p>
<p>Para esto crearemos la función a la que hace referencia el botón “eliminar”, lo que haremos es lo siguiente:</p>
<pre name="code" class="javascript">
onDelete : function(){ //step 1
	var rows = this.grid.getSelectionModel().getSelections(); //step 2

	if(rows.length === 0){  //step 3
		return false;
	}
this.storeGrid.remove(rows);  //step 4
},
</pre>
<p>En el paso uno creamos la función dentro del objeto principal.</p>
<p>En el paso dos tomamos la instancia del “SelectionModel()” de nuestro “Grid”, con esto podemos obtener la información de las filas seleccionadas por el usuario mediante el método “getSelections()”. </p>
<p>En el paso tres lo que hacemos es verificar que el usuario halla seleccionado algo, si no  hay nada seleccionado o la selección del “Grid” esta vacía no se eliminará ningún registro ya que hacemos un return.</p>
<p>En el paso cuatro ya que se verifico que es un registro que puede ser borrado lo elimina del “Grid” usando el método “remove” del store que contiene los records.</p>
<p>Si intentamos hacer esto notaremos que efectivamente se borra del “Grid”, pero no se borra de nuestra base de datos, además nos manda el siguiente error:</p>
<pre name="code" class="javascript">
POST serverside/destroyContact.php  404 Not Found
</pre>
<p>Este es el mismo mensaje que recibimos en las secciones anteriores, ya que aún no tenemos ese archivo PHP; este archivo se encarga de borrar el registro en la base de datos, es muy semejante a los que hemos hecho, su estructura es la siguiente:</p>
<pre name="code" class="php">
&lt;?php	//step 1
	$connection=mysql_connect("localhost","root","") or die("Connection Failed".mysql_error());
	mysql_select_db("test",$connection)or die("Error loading the DataBase".mysql_error());

	$id = json_decode(stripslashes($_POST["data"])); //step 2

	//step 3
	$query = sprintf("DELETE FROM contacts WHERE id = %d",
		mysql_real_escape_string($id));

	$rs  = mysql_query($query);

	//step 4
	echo json_encode(array(
		"success" 	=&gt; mysql_errno() == 0,
		"msg"		=&gt; mysql_errno() == 0?"Contact deleted successfully":mysql_error()
	));
</pre>
<p>En el paso uno lo que hacemos es crear la conexión a la base de datos.</p>
<p>En el paso dos obtenemos la información que nos fue mandada, la descodificamos con Json_decode() y la guardamos en la variable “id”. En este caso solo se nos envió el “id” del registro que se quiere eliminar.</p>
<p>En el paso tres solo hacemos el query para eliminar el registro.</p>
<p>En el paso cuatro mandamos como respuesta un mensaje de éxito y si ocurrió un error se manda el error como respuesta.</p>
<p>Si intentamos eliminar un registro notaremos que esta vez también fue borrado de nuestra base de datos. Y esta sería la respuesta del servidor:</p>
<pre name="code" class="javascript">
{"success":true,"msg":"Contact deleted successfully"}
</pre>
<p>Con esto terminamos la última parte de nuestro CRUD que es eliminar un registro.</p>
<h3>Conclusión </h3>
<p>En esta ocasión vimos como podemos crear, leer, actualizar y eliminar datos usando “HttpProxy”, “JsonReader”, “JsonWriter” y un “Store” esto es muy útil ya que por medio de estas cleses de Extjs no tenemos que hacer las peticiones al servidor manualmente como lo hemos hecho en tutoriales pasados. El “JsonReader” se encarga de leer la información que nos manda el servidor, mientras el  “JsonWriter” codifica la información y hace la petición al servidor.</p>
<p>Si tienes algún comentario o sugerencia no dudes en comunicarnolos viá el formulario inferior, por el <a href="http://foro.quizzpot.com/">foro </a>o en alguna de las redes sociales como <a href="http://twitter.com/quizzpot">Twitter </a>y <a href="http://www.facebook.com/pages/Quizzpot/299875756793?v=wall">Facebook</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.quizzpot.com/2010/10/crud-de-un-catalogo-de-contactos/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Creando un Wizard</title>
		<link>http://www.quizzpot.com/2010/10/creando-un-wizard/</link>
		<comments>http://www.quizzpot.com/2010/10/creando-un-wizard/#comments</comments>
		<pubDate>Tue, 19 Oct 2010 14:00:28 +0000</pubDate>
		<dc:creator>Victor Felipe</dc:creator>
				<category><![CDATA[Español]]></category>
		<category><![CDATA[Ext3]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.quizzpot.com/?p=2671</guid>
		<description><![CDATA[En esta ocasión veremos cómo podemos crear un Wizard, esto lo haremos utilizando un layout de tipo “Card” y un solo formulario, el wizard que simularemos recojerá la información necesaria para crear una conexión a una base de datos.]]></description>
			<content:encoded><![CDATA[<p>En este tutorial veremos la manera de cambiar la información que queremos desplegar en una ventana, esto lo haremos usando un “CardLayout” el cual nos permite cambiar el contenido de una ventana sin tener que actualizar en nuestro explorador, la siguiente imagen el resultado que se obtendrá al final del tutorial.</p>
<p><!-- imagen 1 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/10/wizard-1.png" alt="resultado final" />
<p>Resultado Final</p>
</div>
<h3>Empaquetando el Tutorial</h3>
<p>Vamos a empaquetar el código para evitar conflictos con otras variables o librerías que usemos en nuestro proyecto.</p>
<pre name="code" class="javascript">
Ext.ns(“com.quizzpot.tutorial”);

com.quizzpot.tutorial.Wizard = {
	index	: 0,

	init : function(){
		//code here
	}
}
Ext.onReady(com.quizzpot.tutorial.Wizard.init,com.quizzpot.tutorial.Wizard);
</pre>
<p>Más adelante se explica la propiedad “index” que hemos definido dentro del objeto principal.</p>
<h3>Creando el  Cardlayout</h3>
<p>Lo primero que haremos es crear un formulario el cual contendrá la información que deseamos desplegar a lo largo de nuestro wizard. Dentro de la función “init” colocaremos el siguiente código:</p>
<pre name="code" class="javascript">
this.form = new Ext.FormPanel({	 // step 1
	layout	: "card",	 //step2
	border	: false,
	activeItem	: this.index, 	//step3
	items		: [this.createAllias(), this.createDriver(), this.createCredentials()] //step 4
});
</pre>
<p>En el paso uno solo hicimos una instancia del “FormPanel”.</p>
<p>Lo interesante viene en el paso dos, a estas alturas del curso los layouts que más hemos usado son de tipo “fit” y ”border”, en esta ocasión usaremos uno de tipo “card”, este layout nos permite desplegar todos los “items” de esta instancia uno a la vez, además de proporcionarnos métodos para cambiar entre una “carta” y otra.</p>
<p>En el paso tres lo que hacemos con “activeItem” es indicar cual objeto del arreglo de “items” será el que  se usará cuando se inicie la aplicación, y si recordamos “index” es igual a cero con esto indicamos que queremos el objeto de la posición cero del arreglo “items”.</p>
<p>En el paso cuatro al arreglo “items” le asignamos tres funciones “createAllias()”, “createDriver()” y por último “createCredentials()”, vamos a ir viendo en detalle cada una de estas funciones cuyo objetivo es crear la interface para cada paso del wizard.</p>
<h3>Definición de los pasos en el Wizard</h3>
<p>La primera función será nuestra primera pantalla en la cual debe aparecer un campo donde el usuario asignará un nombre a la conexión, también tendremos una pequeña descripción para asistir al usuario.</p>
<p>La segunda función será la pantalla siguiente esta mostrará un combo en el cual el usuario seleccionará el servidor de base de datos, por ejemplo nuestro combo pude tener valores como: MySQL, Oracle Thin, SQL Server, Informix, etc. Esta información la obtendremos desde una tabla de una base de datos.</p>
<p>La última función creará la última pantalla en la que se capturan las credenciales del servidor, vamos a desplegar algunos campos de texto y uno de tipo password.</p>
<p>Por el momento podemos eliminar o comentar las últimas dos funciones, trabajaremos con ellas un poco más adelante.</p>
<h3>Función “createAllias”</h3>
<p>Como mencionamos antes, esta función lo único que contiene es una pequeña descripción y un formulario para obtener el nombre de la conexión, esto lo haremos de la siguiente manera:</p>
<pre name="code" class="javascript">
createAllias : function(){
	return {
		xtype		: &quot;panel&quot;,
		layout	: &quot;form&quot;,
		border	: false,
		padding	: 10,
		items		: [ {html : &quot;&amp;lt;h1&gt;New Connection Wizard&amp;lt;/h1&gt; &amp;lt;br&gt; “+
“&lt;p&gt;This Connection Wizard will guide you through the steps to setup a&quot;+
&quot;database connection. Make sure you have access to the required JDBC driver files(s) for the database you are&quot;+
&quot;going to access.&lt;br&gt;The information about supported databases and links to download sites for JDBC drivers are available&quot;+
&quot; at &lt;a href=&quot;+&quot;http://www.dbvis.com&quot;+&quot;&gt;http://www.dbvis.com&lt;/a&gt;&lt;/p&gt;&lt;br&gt;&lt;br&gt;&quot;, border : false},

		{xtype     : &quot;textfield&quot;, name : &quot;alias&quot;},
		{html       : &quot;&lt;p&gt;&lt;br&gt;Enter the connection alias for the new data base connection. This is the name you will use to refer this database&quot;+
&quot;connection throughout the application&lt;/p&gt;&quot;, border : false}]

	};
}
</pre>
<p>Lo que hicimos es crear la función donde en el “return” creamos un panel (utilizando su “xtype”) el cual tiene un layout de tipo “form” esto es para que al definir el textfield pueda aparecer correctamente su “Label”, de lo contrario no aparecerá. </p>
<p>Al panel que regresamos le podemos colocar todo lo que deseamos que aparezca en pantalla en el atributo “items”. Con esto tendríamos la primera pantalla lista pero no la podemos ver porque no se ha renderizado el formulario que la contiene.</p>
<p>Para poder ver nuestra pantalla lo que haremos es crear una ventana que tendrá al “form” principal, también colocaremos los botones que usaremos para el cambio entre pantallas.</p>
<pre name="code" class="javascript">
//step 1
this.backBtn = new Ext.Button({text : "Back",handler : this.back,scope : this,hidden:true});
this.nextBtn = new Ext.Button({text : "Next",handler : this.next,scope : this});
this.finishBtn = new Ext.Button({text : "Finish", hidden : true, handler:this.finish,scope:this});

this.win = new Ext.Window({
        title		        : "New Connection Wizard",
        layout		: "fit",
        width		        : 450,
        height		: 400,
	resizable	        : false, //step 2
	bodyCssClass	: "wizard-image", //step 3
	fbar		        : [this.backBtn,this.nextBtn,this.finishBtn], //step 4
	items		        : [this.form] //step 5
});
</pre>
<p>En el paso uno creamos los tres botones que usaremos para el cambio entre pantallas, si notamos los botones “backBtn” y “finishBtn” están ocultos (“hidden”) ya que a estos botones les daremos un uso especial más adelante, si lo deseas puedes comentar la propiedad “handler” ya que no hemos definido las funciones todavía, más adelante lo haremos.</p>
<p>En el paso dos hacemos que no se puedan cambiar las dimensiones de la ventana.</p>
<p>En el paso tres se asigna la clase CSS “wizard-image” al cuerpo de la ventana, esta clase coloca una imagen a la ventana, para esto es necesario definir la clase “wizard-image” en una hoja de estilos o en el documento HTML de la siguiente manera:</p>
<pre name="code" class="css">
.wizard-image{background:transparent url(wizard.png) 10px center no-repeat;padding-left:150px;}
</pre>
<p>Nótese que se ha asignado un padding de 150px a la imagen, esto es para que se despliegue correctamente.</p>
<p>En el paso cuatro se han asignado los botones al “footer bar” (fbar), esto permite posicionarlos en la parte inferior de la ventana.</p>
<p>El paso cinco solamente le asignamos el formulario a la ventana como contenido principal.<br />
Por último es necesario renderizar los componentes que hemos creado, al usar una ventana solamente es necesario ejecutar el método “show” de la instancia “win”.</p>
<pre name="code" class="javascript">
this.win.show();
</pre>
<p><!-- imagen 2 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/10/wizard-2.png" alt="Primera Pantalla" />
<p>Primera Pantalla</p>
</div>
<h3>Función “createDriver”</h3>
<p>Lo siguiente es crear la función “createDriver” que usaremos para la siguiente pantalla como mencionamos antes en esta pantalla el usuario escoge los drivers que usará, esta información será obtenida desde nuestra base de datos y desplegada en un combo. Primero veremos la estructura de la base de datos.</p>
<pre name="code" class="sql">
-- phpMyAdmin SQL Dump
-- version 3.2.0.1
-- http://www.phpmyadmin.net
--
-- Servidor: localhost
-- Tiempo de generación: 19-10-2010 a las 03:58:23
-- 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 `drivers`
--

CREATE TABLE IF NOT EXISTS `drivers` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `database` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `driver` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;

--
-- Volcar la base de datos para la tabla `drivers`
--
</pre>
<p>Tomando en cuenta la definición de la tabla anterior necesitamos exponer la información usando nuestro lenguaje favorito, para este tutorial usaremos PHP, pero bien pueden usar Java, Ruby, Grails o cualquier otro lenguaje.</p>
<pre name="code" class="php">
&lt;?php
	$link=mysql_connect("localhost", "root", "") or die ("Error conectando a la base de datos.");
	mysql_select_db( "test",$link) or die("Error seleccionando la base de datos.");

	$result=mysql_query("SELECT * FROM drivers");

	$drivers=array();
	while($row=mysql_fetch_array($result)){
		array_push($drivers,array(
			"id"		=&gt;$row["id"],
			"database"	=&gt;$row["database"],
			"driver"	=&gt;$row["driver"]
			));
	}

	echo json_encode(
		array(
			"succsess"	=&gt; true,
			"info"		=&gt; $drivers
		)
	);
</pre>
<p>El resultado al ejecutar ese código será el siguiente:</p>
<pre name="code" class="javascript">
{"succsess":true,"info":[{"id":"1","database":"MySQL","driver":"com.mysql.jdbc.Driver"},{"id":"2","database":"Oracle","driver":"oracle.jdbc.driver.OracleDriver"}]}
</pre>
<p>Ya que tenemos la información necesaria lo siguiente es crear el combo y el panel que tendrá la información para la desplegar en pantalla. Lo haremos de la siguiente manera:</p>
<pre name="code" class="javascript">
createDriver : function(){
	//se crea el store
	var store = new Ext.data.JsonStore({ //step 1
		url	:"drivers.php", //archivo donde sacará la información
		root	: "info",
		fields	: [ //campos del store que usará
			{name :"id"},
			{name :"database", type : "string"},
			{name :"driver", type : "string"},
		]
	});

	//se crea el combo asignándole el store
	var combo = new Ext.form.ComboBox({ //step 2
		fieldLabel	        :"Database",
		name		        :"database",
		forceSelection	: true, // esta opción obliga al usuario a seleccionar un valor del combo
		store		        : store, //asignándole el store
		emptyText	        :"pick one DB...", // texto mostrado antes de que se seleccione algo
		triggerAction	: "all", // indica que siempre muestre todos los datos de su store
		editable	        : false, // no se puede editar el contenido
		border		: false,
		width		        : 150,
		displayField	        : "database", //la información que mostrara dentro del combo
		valueField	        : "id" // lo que enviará al servidor
	});

	return { //step 3
		xtype		: "panel",
		layout	: "form",
		padding	: 10,
		labelWidth	: 60,
		border	: false,
		items		: [{html : &quot;&amp;lt;h1&gt;Select Database Driver&amp;lt;/h1&gt;&amp;lt;br&gt;&quot;,border : false},
    combo,
				    {html : &quot;&lt;br&gt;&lt;br&gt;&lt;p&gt;Select the appropriate database driver from the list above.&lt;/p&gt;&quot;,border : false}]
	}
},
</pre>
<p>En el paso uno lo que hicimos fue crear el “store” que nos trae la información que obtenemos en el archivo driver.php, además de que lo configuramos para que pueda interpretar correctamente esa información.</p>
<p>En el paso dos creamos el combo con la información que contiene el store, en el código he comentado algunas configuraciones usadas.</p>
<p>En el paso tres creamos el panel con un layout de tipo ”form” y en “items” le pasamos lo que queremos que contenga este panel, en primer lugar ponemos una descripción usando el atributo “html” luego pasamos el combo y por último se ponen las indicaciones también con un atributo “html”.</p>
<p>Con esto tendríamos la segunda pantalla que es parecida a esta.</p>
<p><!-- imagen 3 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/10/wizard-3.png" alt="segunda pantalla" />
<p>Segunda pantalla</p>
</div>
<h3>Función “createCredentials”</h3>
<p>Por ultimo crearemos el formulario donde el usuario introduce el nombre del servidor, el puerto, la base de datos, el usuario y la contraseña, esto será muy similar a las funciones anteriores:</p>
<pre name="code" class="javascript">
createCredentials : function(){
	return{
		xtype		: "panel",
		layout	: "form",
		labelWidth	: 100,
		padding	: 10,
		border	: false,
		items		: [{html : &quot;&lt;h1&gt;Test&lt;/h1&gt;&lt;br&gt;&lt;br&gt;&quot;, border : false},
				{fieldLabel : &quot;Server&quot;,xtype : &quot;textfield&quot;, name : &quot;server&quot;},
				{fieldLabel : &quot;Port&quot;,xtype : &quot;textfield&quot;, name : &quot;port&quot;},
				{fieldLabel : &quot;Database&quot;,xtype : &quot;textfield&quot;, name : &quot;database&quot;},
				{fieldLabel : &quot;UserID&quot;,xtype : &quot;textfield&quot;, name : &quot;user&quot;},
				{fieldLabel : &quot;Password&quot;,xtype : &quot;textfield&quot;, inputType : &quot;password&quot;, name : &quot;passwrd&quot;},
				{html : &quot;&lt;br&gt;&lt;br&gt;&lt;p&gt;Press the Finish button to create and connect this database connection.&lt;/p&gt;&quot;, border : false}]
	}
},
</pre>
<p>Esta función básicamente funciona como las últimas dos. Lo que hacemos es crear el panel con un layout de tipo “form” y dentro de “items” colocamos lo que contendrá el panel, como lo que deseamos obtener es información que proporciona el usuario usamos “textfied” para que nos crea el campo donde el usuario podrá introducir la información, notemos que en el último “textfield” usamos “inputType” de tipo “password” con la finalidad de que este campo no muestre los caracteres alpha numericos ya que está destinado a para recibir una contraseña. </p>
<p>Con esto tenemos la tercera pantalla:</p>
<p><!-- imagen 4 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/10/wizard-4.png" alt="terceara pantalla" />
<p>Tercera pantalla</p>
</div>
<h3>Avanzar en los pasos del wizard</h3>
<p>Ya que tenemos nuestras pantallas listas lo siguiente es asignarle acciones a los botones que definimos al inicio del tutorial, descomenta la propiedad “handler” de cada botón.</p>
<p>Para avanzar entre las pantallas crearemos la función “next”, de la siguiente manera:</p>
<pre name="code" class="javascript">
next: function(){
	this.backBtn.show();	//step 1
	if(this.index &lt; this.form.items.length-1){	//step 2
		this.index++;
		var cardlayout = this.form.getLayout();	//step 3
		cardlayout.setActiveItem(this.index);

		//step 4
		if(this.index == this.form.items.length-1){	//si esta en el ultima carta
			this.nextBtn.hide();
			this.finishBtn.show();
		}
	}
},
</pre>
<p>En el paso uno simplemente mostramos el botón “back”, esto es porque de inicio está oculto y lo que necesitamos es que se visualice cuando el usuario avanza a la segunda pantalla.</p>
<p>En el paso dos solamente se verifica que no sea el último paso del wizard, la propiedad “this.index” es un contador que nos servirá para saber en cual paso esta el usuario, si no es el ultimo paso entonces se incrementa la propiedad “index” en uno.</p>
<p>El paso dos es importantisimo, aquí tomamos el “CardLayout” que estamos usando para el wizard, el método “getLayout” regresa la instancia del layout que estamos usando. Una vez que tenemos el layout podemos asignarle una nueva carta usando el método “setActiveItem”.</p>
<p>En el paso cuatro revisamos si al cambiar de carta se está desplegando la última, de ser así se ocultará el botón “next” y se mostrará el botón “finish”.</p>
<h3>Retroceder en los pasos del wizard</h3>
<p>Hasta este punto podemos avanzar en el wizard y llegar al final, ahora vamos a darle la opción al usuario de poder retroceder en los pasos del wizard, para eso creamos la función “back” de la siguiente manera.</p>
<pre name="code" class="javascript">
back : function(){
	if(this.index&gt;0){	//step 1
		this.index--;
		var cardlayout = this.form.getLayout();
		cardlayout.setActiveItem(this.index);
	}

//step 2
	if(this.index == 0){	//si está en la primera carta
		this.backBtn.hide();
	}else{	//step 3
		this.finishBtn.hide();
		this.nextBtn.show();
	}
},
</pre>
<p>En el paso uno verificamos que el usuario no esté visualizando el paso número uno del wizard ya que si estamos al inicio no es posible seguir retrocediendo, si “index” es mayor a cero entonces si es posible retroceder y cambiamos la pantalla.</p>
<p>En el paso dos revisamos que si al retroceder el usuario esta viendo el primer paso entonces ocultamos el botón “back”, ya que no es necesario seguir mostrándolo.</p>
<p>El paso tres se ejecuta siempre y cuando no estemos en el primer paso, aquí ocultaremos el botón “finish” y mostraremos el botón “next” ya que si se ha presionado el botón “back” es seguro que ya no estamos en el ultimo paso.</p>
<h3>Finalizando el wizard</h3>
<p>Ya tenemos la funcionalidad básica, el usuario puede avanzar y retroceder entre los pasos que tiene el wizard, ahora tenemos que programar lo que necesitamos realizar cuando el usuario ha concluido con el wizard, esto es cuando da click sobre el botón “Finish”, para esto creamos el handler del botón de la siguiente manera:</p>
<pre name="code" class="javascript">
finish	: function(){
	this.form.getForm().submit({
		url		: "createConnection.php",
		scope	        : this,
		success	: this.msg,
		failure	: this.msg
	});
},
</pre>
<p>Aquí puede ir el código que desees, para este ejemplo solamente se le ha hecho un “submit” al formulario principal enviando la información al archivo “createConnection.php” el cual debería poder gestionar la información recibida y procesarla correctamente, una vez que responde el servidor se ejecutará la función “msg” la cual será algo como lo siguiente:</p>
<pre name="code" class="javascript">
msg	: function(){
	Ext.Msg.alert("Alert","Your connection has been created succesfully.");
	this.win.close();
}
</pre>
<p>Aquí también puedes poner lo que desees, en este caso solamente se despliega un mensaje y además se cierra la ventana del wizard automáticamente.</p>
<h3>Conclusion</h3>
<p>En este tutorial vimos algunos puntos importantes como la creación de un “CardLayout”, también se discutió sobre la manera de moverse sobre las cartas creadas y algo que quiero resaltar es la manera en como usamos un solo formulario para todos los campos que había en las cartas, esto nos permite recolecatar la información de una manera extremadamente sencilla.</p>
<p>Si tienes alguna duda o sugerencia te recomiendo dejarnos un comentario o visitar nuestros foros, cada día va creciendo la comunidad y cuenta con usuarios dispuestos en ayudarte.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.quizzpot.com/2010/10/creando-un-wizard/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Editando una Imagen</title>
		<link>http://www.quizzpot.com/2010/10/editando-una-imagen/</link>
		<comments>http://www.quizzpot.com/2010/10/editando-una-imagen/#comments</comments>
		<pubDate>Thu, 14 Oct 2010 14:00:23 +0000</pubDate>
		<dc:creator>Victor Felipe</dc:creator>
				<category><![CDATA[Español]]></category>
		<category><![CDATA[Ext3]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.quizzpot.com/?p=2642</guid>
		<description><![CDATA[En esta ocasión veremos como interactuar con una imagen por medio de sliders, los cuales nos ayudaran a que este elemento pueda ser editado. Veremos cómo cambiar propiedades básicas de nuestro elemento.]]></description>
			<content:encoded><![CDATA[<p>En este tutorial vamos a modificar mediante los sliders la opacidad y dimensiones de una imagen, esto nos permitirá comprender el uso adecuado de componente “Ext.slier.SingleSlider”, la siguiente imagen es un ejemplo de lo que obtendremos al final del tutorial:</p>
<p><!-- imagen 1 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/10/Slider-1.png" alt="resultado final" />
<p>Resultado Final</p>
</div>
<h3>Empaquetando el Tutorial</h3>
<p>Vamos a empaquetar el código para evitar conflictos con otras variables.</p>
<pre name="code" class="javascript">
Ext.ns(“com.quizzpot.tutorial”);
com.quizzpot.tutorial.SliderTutorial= {
	init : function(){
		//code
	}
}
Ext.onReady(com.quizzpot.tutorial.SliderTutorial.init, com.quizzpot.tutorial.SliderTutorial);
</pre>
<h3>Colocando la Imagen</h3>
<p>Lo primero que haremos es crear la estructura html sobre la cual trabajaremos a lo largo del tutorial.</p>
<pre name="code" class="html">
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot;
	&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;

&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
&lt;title&gt;Demo: Slider | Quizzpot&lt;/title&gt;

&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;../ext-3.2.1/resources/css/ext-all.css&quot; /&gt;
&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;../resources/style.css&quot; /&gt;

&lt;script type=&quot;text/javascript&quot; src=&quot;../ext-3.2.1/adapter/ext/ext-base.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;../ext-3.2.1/ext-all.js&quot;&gt; &lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;slider.js&quot;&gt;&lt;/script&gt;

&lt;style type=&quot;text/css&quot;&gt;
#frame{width:800px;height:400px;margin:50px;}
#canvas{width:595px;height:100%;overflow:hidden;border:1px solid #99BBE8;float:left;}
#tools{width:200px;height:100%;float:right;}
&lt;/style&gt;

&lt;/head&gt;
&lt;body&gt;

	&lt;div id=&quot;frame&quot;&gt;
		&lt;div id=&quot;canvas&quot;&gt;
			&lt;img src=&quot;mac-book-pro.png&quot; id=&quot;img&quot;&gt;
		&lt;/div&gt;
		&lt;div id=&quot;tools&quot;&gt;
		&lt;/div&gt;
	&lt;/div&gt;

&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Lo que hicimos fue crear tres divs, el primero es “frame” este es el div en el cual se encontraran alojados los otros divs que es “canvas” en el cual colocaremos la imagen que editaremos en el tutorial, y por ultimo está el div “tools” este lo usaremos para renderizar el panel con  los slider.</p>
<p>También creamos estilos para nuestros divs con estos estilos posicionamos y les asignamos un tamaño.<br />
Si ejecutamos el html podemos ver que solo tenemos los divs y la imagen, lo primero que haremos es tomar la imagen por su id, el código que aparece  a continuación debe ir en el archivo slider.js dentro de la función init.</p>
<pre name="code" class="javascript">
var el = Ext.get('img'),//step 1
	frame = Ext.get("canvas"); //step 2

el.setWidth("50%"); //step 3
setTimeout(function(){
	el.center(frame);
},500);
</pre>
<p>En el paso uno lo que hacemos es obtener la imagen por medio de su id el cual está definido dentro de nuestro documento html.</p>
<p>En el paso dos obtenemos el div donde está colocada la imagen.</p>
<p>En el paso tres cambiamos el tamaño de la imagen usando “setWidth()”. </p>
<p>Usamos “setTimeout()” para ejecutar la función después del tiempo marcado en milisegundos, esto da tiempo para que a se pueda calcular el nuevo tamaño de la imagen. </p>
<p>Y por último usamos “center()” para colocar la imagen en el centro, si notamos le pasamos como parámetro “frame” esta causara que se centre dentro del div “canvas” que es el espacio que dedicamos para colocar nuestra imagen.</p>
<p><!-- imagen 2 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/10/Slider-2.png" alt="colocando la imagen" />
<p>Colocando la Imagen</p>
</div>
<h3>Creando los Sliders</h3>
<p>Ya que tenemos nuestra imagen lista, lo siguiente es colocar los sliders “size” y “opacity” con los cuales podremos manipular el tamaño y la trasparencia de nuestra imagen, lo haremos de la siguiente manera: </p>
<pre name="code" class="javascript">
var size = new Ext.slider.SingleSlider({ //step 1
	fieldLabel	: "Size",
	width		: 100, // el tamaño que tendrá el slider
	minValue	: 20, // el valor mínimo que se obtendrá del slider
	maxValue	: 120, //el valor máximo que obtendrá el slider
	value		: 50, //valor inicial que tendrá el slider
	plugins		: tip
});

var opacity = new Ext.slider.SingleSlider({ //step 2
	fieldLabel	: "Opacity",
	width		: 100,
	increment	: 10, // el slider tendrá un aumento de 10 en 10
	minValue	: 0,
	maxValue	: 100,
	value		: 100,
	plugins		: tip //step 3
});
</pre>
<p>En el paso uno creamos el slider “size”, y si vemos en el paso dos se crea el slider “opacity” ambos tienen los mismos atributos solo cambia el atributo “imcremenent” que se encuentra en “opacity”. </p>
<p>Notemos que estamos usando un “SingleSlider” ya que este componente nos permite renderizarlo verticalmente si es que lo deseamos.</p>
<p>En el paso tres lo que hacemos es pasarle los “tips” a los sliders vía “plugins” pero para esto tenemos que crearlos antes de crear los sliders, lo haremos dela siguiente manera:</p>
<pre name="code" class="javascript">
Ext.QuickTips.init(); //step 1

var tip = new Ext.slider.Tip({ // step 2
	getText: function(thumb){ // step 3
		return String.format('{0}%', thumb.value);
	}
});
</pre>
<p>En el paso uno iniciamos los QuickTip, es importante que esto solo se tiene que declarar una vez en todo el proyecto.</p>
<p>En el paso dos creamos una instancia de “Ext.slider.Tips” y en el paso tres lo que hacemos es sobre escribir el método “getText” esto es con el fin de que en el tip se vea el signo “%” de lo contrario solo se desplegará el valor del slider.</p>
<p>Ya que tenemos nuestros sliders lo siguiente es colocarlos en un panel para poder mostrarlos, el panel quedaría de la siguiente manera:</p>
<pre name="code" class="javascript">
new Ext.Panel({
	renderTo	: "tools",
	title		: "Settings",
	collapsible	: true,
	labelWidth	: 60,
	layout		: "form",
	frame		: true,
	items		: [size,opacity]
});
</pre>
<p>Con esto el resultado debe ser parecido a esto:</p>
<p><!-- imagen 3 --></p>
<div class="example">
<img src="http://www.quizzpot.com/wp-content/uploads/2010/10/Slider-3.jpg" alt="Sliders dentro del panel" />
<p>Sliders Dentro del Panel</p>
</div>
<h3>Interactuando con la Imagen</h3>
<p>Ya que tenemos listo nuestros slider lo siguiente es crear las funciones que harán que nuestra imagen pueda cambiar de tamaño y el valor de la opacidad.</p>
<pre name="code" class="javascript">
size.on("change",function(slider,value){
	el.setWidth(value+"%")
	el.center(frame);
});
</pre>
<p>Lo que el código anterior hace es usar el evento “change”  el cual se ejecuta cuando el usuario cambia el valor del slider, recibe como parámetros el slider mismo y el nuevo valor, por ultimo usamos nuevamente “set.Width()” y le pasamos como parámetro el valor que se obtiene del slider, con esto podemos cambiar el tamaño de la imagen, es importante mencionar que no es necesario cambiar la altura de la foto ya que el navegador la calcula basándose el ancho de esta.</p>
<p>Por ultimo solo centramos la foto en el div para que después del cambio de tamaño, siempre este en el centro, recuerda que le pasamos “frame” para que lo centre en el div contenedor.</p>
<p>Lo siguiente es cambiar la opacidad de la foto y eso lo haremos de una manera similar :</p>
<pre name="code" class="javascript">
opacity.on("change",function(slider,value){
	el.setOpacity(value/100);
});
</pre>
<p>Básicamente es lo mismo que hicimos para cambiar el tamaño la única diferencia es que usamos “seOpacity()” y le damos el valor del slider, notemos que ese valor es dividido entre cien esto es porque la opacidad es manejada de 0 a 1 por lo cual .5 sería el valor 50 del slider.</p>
<h3>Conclusión </h3>
<p>En esta ocasión vimos cómo crear sliders, y darles un uso básico. Estos son muy útiles cuando deseamos hacer cambios a ciertos elementos de nuestro sistema, modificar rangos, etc.</p>
<p>Si tienes alguna duda o comentario por favor coméntenlo en el <a href="http://foro.quizzpot.com/">foro</a>, recuerden seguirnos en Twitter (<a href="http://twitter.com/quizzpot">@quizzpot</a>) o <a href="http://www.facebook.com/pages/Quizzpot/299875756793?v=wall">Facebook</a> para estar al tanto de las actualizaciones.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.quizzpot.com/2010/10/editando-una-imagen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Show information from JSON format</title>
		<link>http://www.quizzpot.com/2010/10/show-information-from-json-format/</link>
		<comments>http://www.quizzpot.com/2010/10/show-information-from-json-format/#comments</comments>
		<pubDate>Wed, 13 Oct 2010 14:00:04 +0000</pubDate>
		<dc:creator>Crysfel</dc:creator>
				<category><![CDATA[English]]></category>
		<category><![CDATA[Ext3]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.quizzpot.com/?p=2264</guid>
		<description><![CDATA[In this tutorial I want to show how to load the information contained in JSON format in a "Grid", is really easy and basic, but I think it is important to mention for those who are starting to work with this library.]]></description>
			<content:encoded><![CDATA[<p>This tutorial is very similar to the previous one where we saw how to <a href="http://www.quizzpot.com/2010/01/show-information-from-an-xml-file/">load data from an XML file</a>, the only thing we will change from the previous tutorial is the record that specifies the information it will contain and the &#8220;reader&#8221; because now we want to be able to read the JSON information returned by the server.</p>
<p><!-- image 1 --></p>
<div class="example"><img src="http://www.quizzpot.com/wp-content/uploads/2009/07/gridjson1.jpg" alt="Image of the grid" />
<p>Final Image</p>
</div>
<h3>Resources</h3>
<p>Let&#8217;s download the <a href="http://www.quizzpot.com/wp-content/uploads/2009/07/gridjson.zip">resources</a> for this tutorial, unzip them and copy the files inside of the folder &#8220;grid&#8221; on our Web server already installed.</p>
<h3>Packaging the tutorial</h3>
<p>As we have always done it in this course, we will package the code we will use for this tutorial, remember that this is fundamental and very important, believe me I will never get tired of saying this.</p>
<pre name="code" class="javascript">
Ext.ns('com.quizzpot.tutorial');

com.quizzpot.tutorial.GridJsonTutorial = {
	init: function(){
		//code goes here
}

Ext.onReady(com.quizzpot.tutorial.GridJsonTutorial.init,com.quizzpot.tutorial.GridJsonTutorial);
</pre>
<h3>The JSON we&#8217;re going to use</h3>
<p>Now let&#8217;s define the information that the grid will display, for simplicity I will write the information directly into the code, but remember that this information can be in a database, a text file, Web service or it can come from elsewhere, but for now we will &#8220;hardcoded&#8221; it.</p>
<pre name="code" class="php">
&lt;?php
	header(&quot;Content-Type: text/plain&quot;); 

	$data = array(
		'success'=&gt;true,
		'total'=&gt;11,
		'data'=&gt;array(
			array('city'=&gt;'Mexico city','visits'=&gt;684,'pageVisits'=&gt;4.11,'averageTime'=&gt;'00:06:53'),
			array('city'=&gt;'La Victoria','visits'=&gt;443,'pageVisits'=&gt;4.39,'averageTime'=&gt;'00:07:28'),
			array('city'=&gt;'Madrid','visits'=&gt;380,'pageVisits'=&gt;3.11,'averageTime'=&gt;'00:05:22'),
			array('city'=&gt;'Providencia','visits'=&gt;204,'pageVisits'=&gt;3.83,'averageTime'=&gt;'00:08:20'),
			array('city'=&gt;'Bogota','visits'=&gt;204,'pageVisits'=&gt;3.26,'averageTime'=&gt;'00:04:57'),
			array('city'=&gt;'Puerto Madero','visits'=&gt;192,'pageVisits'=&gt;3.56,'averageTime'=&gt;'00:05:07'),
			array('city'=&gt;'Monterrey','visits'=&gt;174,'pageVisits'=&gt;3.90,'averageTime'=&gt;'00:06:06'),
			array('city'=&gt;'Barcelona','visits'=&gt;145,'pageVisits'=&gt;3.28,'averageTime'=&gt;'00:05:39'),
			array('city'=&gt;'Caracas','visits'=&gt;132,'pageVisits'=&gt;4.55,'averageTime'=&gt;'00:06:27'),
			array('city'=&gt;'Rosario','visits'=&gt;116,'pageVisits'=&gt;2.44,'averageTime'=&gt;'00:04:30'),
			array('city'=&gt;'Oaxaca','visits'=&gt;108,'pageVisits'=&gt;1.73,'averageTime'=&gt;'00:02:37')
		)
	);

	echo json_encode($data);
?&gt;
</pre>
<h3>Creating the “Record”</h3>
<p>Once we have defined the format in which the information is delivered to the client (via AJAX), we can create the &#8220;Record&#8221; we will display in the table.</p>
<pre name="code" class="javascript">
var Record = Ext.data.Record.create([
	{name: 'city'},
	{name: 'visits', type:'float'},
	{name: 'pageVisits', type:'float'},
	{name: 'averageTime'}
]);
</pre>
<p>The previous code should look familiar because we have reviewed in <a href="http://www.quizzpot.com/2009/06/reading-information-in-json-format/">previous tutorials</a>, basically we create a &#8220;record&#8221; with the fields we need to display and that are returned by the server, and define (in some cases) the type of information of the field.</p>
<h3>Creating the “Reader”</h3>
<p>Now let&#8217;s write the &#8220;Reader&#8221; so the store can interpret the information given to us in JSON format.</p>
<pre name="code" class="javascript">
var reader = new Ext.data.JsonReader({
   totalRecords: "total",
   root: "data"
}, Record);
</pre>
<p>For this case we used the component &#8220;JsonReader&#8221; and we configured the field of the total of records and the root field which is the principal information.</p>
<h3>Creating the Store and loading the information</h3>
<p>The next thing we need to do is create the store which shall contain the information locally in order to be manipulated by the grid.</p>
<pre name="code" class="javascript">
var store = new Ext.data.Store({
	url: 'gridjson.php',
	reader: reader
});

store.load();
</pre>
<p>You can see that we have configured the &#8220;url&#8221; that we are going to use to request the information with Ajax, also we have assigned the &#8220;Reader&#8221; we created earlier, finally we &#8220;load&#8221; the store.</p>
<h3>Saving a few lines of code</h3>
<p>So far all we&#8217;ve done is get the information from the server and save it on the store, all the previous lines of code can be reduced substantially as follows:</p>
<pre name="code" class="javascript">
var store = new Ext.data.JsonStore({
	url: 'gridjson.php',
	root: 'data',
	fields: ['city',{name:'visits',type:'float'},{name:'pageVisits',type:'float'},'averageTime']
});

store.load();
</pre>
<p>With the previous lines we do exactly the same as we did before, this is convenient when using JSON as a format for information transfer, so the decision to do it in one way or another is up to the developer.</p>
<h3>Creating the Grid</h3>
<p>Let&#8217;s create the grid to display the information contained in the store we created previously.</p>
<pre name="code" class="javascript">
var grid = new Ext.grid.GridPanel({
	store: store, // <--- we assign the store with the information we're going to use
	columns: [
		new Ext.grid.RowNumberer(),
		{header:'City', dataIndex:'city',sortable: true},
		{header:'Visits', dataIndex:'visits',sortable: true},
		{header:'Page/Visits', dataIndex:'pageVisits',sortable: true},
		{header:'Average Time', dataIndex:'averageTime', width:150,sortable: true}
	],
	border: false,
	stripeRows: true
});
</pre>
<p>We're not doing anything special, we only assigned the store to use, we defined the columns and assign a proper of the "Record" in the store to each column, we also created a column where the rows are numbered, we removed the border so when a table is entered the window will look good and at last we added alternating lines to the rows.</p>
<h3>Displaying the grid</h3>
<p>There are several ways to display the grid on the screen, this time we will use a window.</p>
<pre name="code" class="javascript">
var win = new Ext.Window({
	title: 'Grid example',
	layout: 'fit',
	width: 510,
	height:350,
	items: grid
});

win.show();
</pre>
<p>If you update the browser you will see something like the following image.</p>
<p><!-- imagen 1 --></p>
<div class="example"><img src="http://www.quizzpot.com/wp-content/uploads/2009/07/gridjson1.jpg" alt="Image of the grid" />
<p>Final Image</p>
</div>
<h3>Conclusions</h3>
<p>So far we have seen how to display information in different formats, which is really simple. In the next chapter we will see how to page this information, every time it gets more interesting so don't forget to subscribe to the Feeds or by email, also remember that use Twitter (quizzpot) to show updates and what we are doing in Quizzpot.</p>
<p>If you have any questions or suggestions please leave your comments and don't forget to become a fan in our Facebook page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.quizzpot.com/2010/10/show-information-from-json-format/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

