<?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>Desarrollosweb.net &#187; Ext.GridPanel</title>
	<atom:link href="http://www.desarrollosweb.net/tag/extgridpanel/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.desarrollosweb.net</link>
	<description>Desarrollo de webs y aplicaciones</description>
	<lastBuildDate>Fri, 26 Mar 2010 10:53:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Cookbook ExtJS: Cargar un registro de un GridPanel en un FormPanel</title>
		<link>http://www.desarrollosweb.net/2008/12/03/cookbook-extjs-cargar-un-registro-de-un-gridpanel-en-un-formpanel/</link>
		<comments>http://www.desarrollosweb.net/2008/12/03/cookbook-extjs-cargar-un-registro-de-un-gridpanel-en-un-formpanel/#comments</comments>
		<pubDate>Wed, 03 Dec 2008 09:40:14 +0000</pubDate>
		<dc:creator>Javier Caride</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[desarrollo web]]></category>
		<category><![CDATA[Ext.Form]]></category>
		<category><![CDATA[Ext.GridPanel]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.desarrollosweb.net/?p=51</guid>
		<description><![CDATA[¿Como hacemos para cargar los datos de un registro de un grid en un formulario? Bien, hay diversas opciones (siempre a gusto del programador) así que aquí vamos a explicar una de ellas: asociar el evento &#8216;rowdblclick&#8217; (doble click en una fila) a un handler que cargue el formulario con los datos del registro. GestorCuentas.movimientosGrid.on('rowdblclick',function( [...]]]></description>
			<content:encoded><![CDATA[<p>¿Como hacemos para cargar los datos de un registro de un grid en un formulario? Bien, hay diversas opciones (siempre a gusto del programador) así que aquí vamos a explicar una de ellas: asociar el evento &#8216;rowdblclick&#8217; (doble click en una fila) a un handler que cargue el formulario con los datos del registro.</p>
<pre name="code" class="javascript">
GestorCuentas.movimientosGrid.on('rowdblclick',function( grid, row, evt) {
        var movRecord = GestorCuentas.movimientosDataStore.getAt(row);
        GestorCuentas.movForm.getForm().load({
            url : 'cargaMovimiento.php',
            method: 'POST',
            params: {
                mov_id: movRecord.data.mov_id
            },
            waitMsg : 'Espere por favor'
        });
    });
</pre>
<p>En el API de ExtJS podemos comprobar que cuando asignamos una función al evento &#8216;rowdbclick&#8217; vamos a recibir tres parámetros: el grid que ha generado el evento, el índice del registro dentro del store y un objeto con datos adicionales del evento</p>
<p>Para quedarnos con el registro, sólo tenemos que solicitarle al store del grid que nos devuelva aquel cuyo índice hemos recibido por parámetro</p>
<pre name="code" class="javascript">
var movRecord = GestorCuentas.movimientosDataStore.getAt(row);
</pre>
<p>Ahora en movRecord tendremos el registro y podremos acceder a sus datos para quedarnos con el identificador del registro. Fijáos que en la definición del record del grid hemos incluído la Primary Key del registro en base de datos, aunque no lo estemos mostrando en el propio grid</p>
<p>Fijáos que el formulario que vamos a cargar tiene asignado un reader, de forma que podemos llamar al método load() del mismo para que automáticamente cargue los datos. Obviamente hay que indicarle que registro se va a cargar por lo que le pasamos como parámetro el mov_id del registro que hemos pedido al store</p>
<p>La instancia del formulario se la pedimos al FormPanel mediante el método getForm(). Esto nos devuelve un objeto Ext.form.BasicForm. Este método tiene un método load() al que le pasamos la configuración necesaria para hacer la carga</p>
<pre name="code" class="javascript">
    GestorCuentas.movForm.getForm().load({
            url : 'cargaMovimiento.php',
            method: 'POST',
            params: {
                // OJO, los datos del registro están en movRecord.data y no directamente en movRecord como podría pensarse
                mov_id: movRecord.data.mov_id
            },
            waitMsg : 'Espere por favor'
        });
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.desarrollosweb.net/2008/12/03/cookbook-extjs-cargar-un-registro-de-un-gridpanel-en-un-formpanel/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Introducción a los Grids en ExtJS</title>
		<link>http://www.desarrollosweb.net/2008/11/18/introduccion-a-los-grids-en-extjs/</link>
		<comments>http://www.desarrollosweb.net/2008/11/18/introduccion-a-los-grids-en-extjs/#comments</comments>
		<pubDate>Tue, 18 Nov 2008 12:27:05 +0000</pubDate>
		<dc:creator>Javier Caride</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[desarrollo web]]></category>
		<category><![CDATA[Ext.EditorGridPanel]]></category>
		<category><![CDATA[Ext.GridPanel]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.desarrollosweb.net/?p=39</guid>
		<description><![CDATA[En ExtJS tenemos básicamente dos tipos de grids, los que únicamente son para listar información (los llamaremos Grids básicos) y los grids editables, que permiten editar la información que se lista dentro de ellos. Grid básico En los grids tenemos que distinguir 3 partes importantes: El store de datos El modelo de datos de las [...]]]></description>
			<content:encoded><![CDATA[<p>En ExtJS tenemos básicamente dos tipos de grids, los que únicamente son para listar información (los llamaremos Grids básicos) y los grids editables, que permiten editar la información que se lista dentro de ellos.</p>
<h2>Grid básico</h2>
<p>En los grids tenemos que distinguir 3 partes importantes:</p>
<ul>
<li>El store de datos</li>
<li>El modelo de datos de las columnas</li>
<li>La definición del grid en sí</li>
</ul>
<p><strong>El store de datos</strong>, es el objeto que se encarga de almacenar los datos que se van a mostrar en el grid. Básicamete se tratan de arrays de datos, pero su particularidad es que pueden leer los datos desde diversas fuentes:</p>
<ul>
<li>Estáticas: ficheros XML o variables de tipo array</li>
<li>Dinámicas: servicios de datos XML o JSON</li>
</ul>
<p>En la definición de un store tenemos que tener en cuenta dos aspectos importantes: el formato de los datos, que nos va a indicar qué tipo de reader necesitamos configurar y si el origen de dato es remoto, configurar el proxy de lectura de datos</p>
<p><strong>El modelo de datos de las columnas</strong> nos define qué datos se van a mostrar en el grid, con qué formato, y de donde se extraen los datos. Hay que tener en cuenta que aunque en un registro se lean muchos campos, podemos elegir cuales mostrar y cuales no.</p>
<h3>Pasos para configurar un grid</h3>
<p>Primero definimos el formato de cada registro, aquí configuramos cuantos campos hay y de que tipo</p>
<pre name="code" class="javascript">    /*
     * Creamos el registro de datos
     */
    var categoriesRecord = new Ext.data.Record.create([
        {name: 'cad_id', type: 'int'},
        {name: 'cad_name', type: 'string'},
        {name: 'cad_date', type: 'date', dateFormat: 'Y-m-d'},
        {name: 'cad_description', type: 'string'}
    ]);</pre>
<p>Después, configuramos el lector de datos. Como se dijo antes, el lector de datos será diferente dependiendo del formato de los datos que obtengamos. En este caso estamos definiendo que los datos nos vendrán codificados en JSON</p>
<pre name="code" class="javascript">    /*
     * Creamos el reader de datos
     */
    var categoriesGridReader = new Ext.data.JsonReader({
        root: 'data',
        totalProperty: 'total',
        id: 'cad_id'},
        categoriesRecord
    );</pre>
<p>La configuración del reader es fácil de entender:</p>
<ul>
<li>Mediante el campo root, indicamos la etiqueta bajo la que llegarán los datos, en este caso &#8216;data&#8217;</li>
<li>El campo totalProperty nos indica en qué etiqueta nos llega el número total de registros</li>
<li>El campo id, nos indica en qué campo nos llega la identificación del registro</li>
</ul>
<p>Una vez tenemos configurado el registro y el reader, definimos el proxy de datos (para una carga remota de los mismos).</p>
<pre name="code" class="javascript">    /*
     * Creamos el proxy para lectura remota de datos
     */
    var categoriesDataProxy = new Ext.data.HttpProxy({
        url: 'scripts/categoriesService.php',   // Servicio web
        method: 'POST'                          // Método de envío
    });</pre>
<p>En este caso, vemos que la carga la hacemos a través de un script php.El cual nos debe devolver un JSON como el siguiente:</p>
<pre name="code" class="javascript">{
    "total":3,
    "data":[
        {
            "cad_id":1,
            "cad_name":"Categoría 1",
            "cad_description":"Descripción de la primera categoría",
            "cad_date": "2008-10-01"
        },{
            "cad_id":2,
            "cad_name":"Categoría 2",
            "cad_description":"Descripción de la segunda categoría",
            "cad_date": "2008-10-11"
        },{
            "cad_id":3,
            "cad_name":"Categoría 3",
            "cad_description":"Descripción de la tercera categoría",
            "cad_date": "2008-10-20"
        },{
            "cad_id":4,
            "cad_name":"Categoría 4",
            "cad_description":"Descripción de la cuarta categoría",
            "cad_date": "2008-10-21"
        },
    ]
}</pre>
<p>Para ello, el php de prueba tiene este contenido</p>
<pre name="code" class="php">$retValue = array(
    'total' =&gt; 4,
    'data' =&gt; array(
        array(
            'cad_id' =&gt; 1,
            'cad_name' =&gt; 'Categoría 1',
            'cad_description' =&gt; 'Descripción de la primera categoría',
            'cad_date' =&gt; '2008-10-01'
        ),
        array(
            'cad_id' =&gt; 2,
            'cad_name' =&gt; 'Categoría 2',
            'cad_description' =&gt; 'Descripción de la segunda categoría',
            'cad_date' =&gt; '2008-10-11'
        ),
        array(
            'cad_id' =&gt; 3,
            'cad_name' =&gt; 'Categoría 3',
            'cad_description' =&gt; 'Descripción de la tercera categoría',
            'cad_date' =&gt; '2008-10-20'
        ),
        array(
            'cad_id' =&gt; 4,
            'cad_name' =&gt; 'Categoría 4',
            'cad_description' =&gt; 'Descripción de la cuarta categoría',
            'cad_date' =&gt; '2008-10-21'
        )
    )
);
echo json_encode($retValue);</pre>
<p>En el caso de scripts php, primero hay que crear en un array la estructura que queramos devolver y después codificar mediante al función json_encode (PHP5), o bien (en PHP4) utilizar la librería de codificación JSON que provee PEAR</p>
<p>Hay que tener en cuenta una cosa JSON, trabaja únicamente en UTF-8, por lo que si los datos los extraemos por ejemplo de una base de datos configurada en ISO-8859-1, <strong>HAY QUE CONVERTIRLOS A UTF-8</strong>, obligatoriamente.</p>
<p>Ahora ya tenemos todos los elementos necesarios para configurar el store del grid:</p>
<pre name="code" class="javascript">    /*
     * Creamos el datastore donde se van a almacenar los datos de la tabla
     */
    var categoriesDataStore = new Ext.data.Store({
        id: 'categoriesDS',
        //Indicamos de donde se va a leer los datos, en este caso un servicio web
        proxy: categoriesDataProxy,
        // Parámetros base que se enviarán al script
        baseParams: {
            language: "es_ES"
        },
        // Indicamos el reader, es decir el procesador de los datos
        reader: categoriesGridReader
    });</pre>
<p>Ya por último, antes de definir el grid en sí, definimos cuales van a ser nuestras columnas, su tipo, ancho, etc.</p>
<pre name="code" class="javascript">    var categoriesColumnMode = new Ext.grid.ColumnModel(
        [{
            header: '#',
            dataIndex: 'cad_id',
            width: 50,
            hidden: false
        },{
            header: 'Categoría',
            dataIndex: 'cad_name',
            width: 150
        },{
            header: 'Descripción',
            dataIndex: 'cad_description',
            width: 300
        },{
            header: 'Fecha',
            dataIndex: 'cad_date',
            width: 90,
            renderer: Ext.util.Format.dateRenderer('d/m/Y')
        }]
    );</pre>
<p>Ahora ya tenemos todos los elementos necesarios para configurar el grid:</p>
<pre name="code" class="javascript">    var categoriesGrid = new Ext.grid.GridPanel({
        id: 'cat_categoriesGrid',
        store: categoriesDataStore,
        cm: categoriesColumnMode,
        enableColLock:false,
        selModel: new Ext.grid.RowSelectionModel({singleSelect:false})
    });</pre>
<p>Sólo nos falta poner todo dentro de un bloque Ext.onReady y definir una ventana para poder visualizar el grid.</p>
<h2>Grid editable</h2>
<p>Además de los grids básicos, ExtJS permite definir grids en los que se puedan editar valores. Para convertir un grid no editable a uno editable, tenemos que hacer cambios en dos lugares: en el ColumnModel y en la definición del grid En el Column mode, hay que incluir una etiqueta &#8216;editor&#8217; en aquellas columnas que queramos hacer editables. En esta etiqueta los que se pone es la definición de un campo editable cuyo objeto puede ser cualquiera de los que hay disponibles para los formularios (cajas de texto, combos, fechas, tiempo&#8230;)</p>
<pre name="code" class="javascript">    var categoriesColumnMode = new Ext.grid.ColumnModel(
        [{
            header: '#',
            dataIndex: 'cad_id',
            width: 50,
            hidden: false
        },{
            header: 'Categoría',
            dataIndex: 'cad_name',
            width: 150,
            editor: new Ext.form.TextField({})

        },{
            header: 'Descripción',
            dataIndex: 'cad_description',
            width: 300,
            editor: new Ext.form.TextField({})
        },{
            header: 'Fecha',
            dataIndex: 'cad_date',
            width: 90,
            renderer: Ext.util.Format.dateRenderer('d/m/Y'),
            editor: new Ext.form.DateField({})
        }]
    );</pre>
<p>La modificación del grid es &#8220;más fácil&#8221;. En este caso sólo hay que heredar de otra clase distinta: EditorGridPanel</p>
<pre name="code" class="javascript">    var categoriesGrid = new Ext.grid.EditorGridPanel({
        id: 'cat_categoriesGrid',
        store: categoriesDataStore,
        cm: categoriesColumnMode,
        enableColLock:false,
        selModel: new Ext.grid.RowSelectionModel({singleSelect:false})
    });</pre>
<p>Al ejecutar el ejemplo, podemos ver que al hacer doble click en cualquiera de los campos editables, se nos permite cambiar el valor del campo y que dicho cambio queda marcado en la esquina superior izquierda con un pequeño icono rojo</p>
<h2>Tratando los cambios en un grid editable</h2>
<p>De nada nos sirve tener un grid editable si no tratamos los datos, pues todos los cambios que se hagan en un grid editable son cambios en el store local.</p>
<p>ExtJS no ofrece ningún mecanismo para automatizar el guardado de datos, dejando a elección del programador la elección del método. Por ejemplo, podemos hacer actualizaciones campo a campo, capturando el evento de cambio de una celda, o bien podemos enviar todos los cambios de una vez mediante la acción en algún botón o componente</p>
<p>Qué método utilizar queda a elección del desarrollador según las circunstancias en las que se  encuentre. En este caso vamos a explicar cómo se haría un envío de todos los cambios. Para ello vamos a coger el ejemplo anterior y primeramente añadir un botón de actualización de cambio situado en una barra de herramientas superior</p>
<pre name="code" class="javascript">    var categoriesGridTopbar = new Ext.Toolbar({
        id: 'categoriesGridTopbarId',
        items: [
            '-&gt;',
            {
                xtype:'button',
                text:'Guardar Cambios',
                id: 'portadas_ToolbarTop_btn0',
                handler:categoriesGridTopbarHnd,
                type:'button'
            }
        ]
    });</pre>
<p>Como se puede ver, se a asignado un handler al botón, que será el que tenderá la petición de guardado de cambios y que contendrá toda la lógica de actualización</p>
<p>En el handler, lo que hemos hecho es crear una llamada Ajax que envíe al servidor todos los cambios, para ello se pide al store un array con todos los registros que han cambiado, se recorre y se  almacena en un array los datos necesarios para enviar. Este array se codifica en JSON y se envía como una variable POST normal. Después es tarea del script php (o Java, o lo que sea) de tratar el array de cambios y realizar las actualizaciones pertinentes.</p>
<pre name="code" class="javascript">    var failureAjaxFn = function(response, request) {
        Ext.Msg.show({
            title: 'Error',
            msg: 'Cambios no guardados. Status:' + response.status,
            buttons: Ext.Msg.OK,
            animEl: 'elId',
            icon: Ext.MessageBox.ERROR
        });
    }

    var successAjaxFn = function(response, request) {
        /*
         * En response.responseText tenemos la respuesta del script, en este caso
         * la salida del script PHP es JSON con lo que tenemos que decodificarlo
         */
        var jsonData = Ext.util.JSON.decode(response.responseText);

        if (true == jsonData.success) {
            Ext.Msg.show({
                title: 'Operación completada',
                msg: jsonData.message,
                buttons: Ext.Msg.OK,
                animEl: 'elId',
                icon: Ext.MessageBox.INFO
            });

            /*
             * PASO IMPORTANTE
             * Para indicar al store que los cambios se han realizado correctamente
             * y eliminar los indicadores de que hay cambios pendientes de guardar
             * hay que llamar
             */
            categoriesDataStore.commitChanges();

        } else {
            Ext.Msg.show({
                title: 'Error',
                msg: jsonData.message,
                buttons: Ext.Msg.OK,
                animEl: 'elId',
                icon: Ext.MessageBox.ERROR
            });
        }
    }
var categoriesGridTopbarHnd = function (e,o) {
    	/*
    	 * Pedimos al store que nos devuelva los registros modificados
    	 */
        var modifiedRecords = categoriesDataStore.getModifiedRecords()

        if (modifiedRecords.length > 0) {
        	/*
             * Creamos un array con los datos de los registros que han cambiado
             */
        	var changes = new Array();
            for (var i=0; i &lt; modifiedRecords.length; i++){
                changes.push(modifiedRecords[i].data);
            }

            /*
             * Codificamos los cambios en JSON
             */
            changes = Ext.util.JSON.encode(changes);

            Ext.Ajax.request({
                url: 'salvarDatos.php',
                method: 'POST',
                success: successAjaxFn,
                failure: failureAjaxFn,
                timeout: 30000,
                params: {
                    operation: 'update',
                    changes: changes
                }
            });
        }
    }
</pre>
<h2>Grids paginados</h2>
<p>Uno de las barras de herramientas más utilizadas con los grids es la de paginación. Su utilización es<br />
bastante sencilla. Primero creamos la barra de paginación:</p>
<pre name="code" class="javascript">    var categoriesPagingBar = new Ext.PagingToolbar({
        pageSize: 10,
        store: categoriesDataStore,
        displayInfo: true
    });</pre>
<p>Su uso es sencillo, sólo tenemos que indicar cual es el store, y el tamaño de página. Después de definirlo<br />
se lo asociamos al grid, para lo que sólo tenemos que indicar en la configuración<br />
lo siguiente &#8220;bbar: categoriesPagingBar&#8221;:</p>
<pre name="code" class="javascript">    var categoriesGrid = new Ext.grid.EditorGridPanel({
        id: 'cat_categoriesGrid',
        store: categoriesDataStore,
        cm: categoriesColumnMode,
        enableColLock:false,
        tbar: categoriesGridTopbar,
        bbar: categoriesPagingBar,
        selModel: new Ext.grid.RowSelectionModel({singleSelect:false})
    });</pre>
<p>Después en la carga inicial de datos, indicamos que queremos cargar la primera página de resultados<br />
y el número de ellos</p>
<pre name="code" class="javascript">categoriesDataStore.load({params: {start: 0, limit: 10}});</pre>
<p>Y después de esto ya no nos tenemos que preocupar de nada más, pues cada vez que hagamos click en los botones el store nos enviará dos variables nuevas: start y limit, al estilo de las paginaciones clásicas</p>
]]></content:encoded>
			<wfw:commentRss>http://www.desarrollosweb.net/2008/11/18/introduccion-a-los-grids-en-extjs/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
	</channel>
</rss>
