Combos dependientes en ExtJS
Nov 18, 2009 | Español | By Hazel | 12 Comments | Read in EnglishEn ocasiones la información que manejamos en nuestras aplicaciones está agrupada en categorías, en estas situaciones unos combos dependientes nos ayudarán a capturar estas relaciones de una manera sencilla.
En el tutorial de hoy haremos dos combos que tienen relación entre sí, usaremos el típico ejemplo de mostrar los países con sus estados, la información del combo de estados será cargada con Ajax dependiendo del país seleccionado en el primer combo, te recomiendo probar la demostración para que puedas observar el resultado final.
Ejemplo del tutorial
Material de apoyo
Para continuar es necesario descargar el material de apoyo y copiarlo dentro de un servidor Web ya que estaremos usando Ajax para cargar la información.
La fuente de información
Vamos a escribir el código necesario para generar la información que desplegarán los combos, para este ejemplo la información estará en arreglos de PHP, pero recuerda que puede salir de una base de datos, un servicio Web (Web Service), un archivo de texto o de cualquier otro lugar.
$countries = array('Argentina','España','México','Perú','United States'); //step 1
$states = array( //step 2
array('Buenos Aires','Córdoba','La Pampa','Mendoza','Santa Fe'),
array('Asturias','Valencia','Barcelona','Toledo'),
array('Distrito Federal','Nuevo León','Jalisco'),
array('Arequipa','Puno','Tacna','Lima'),
array('Texas','California','New york','Virginia')
);
En el paso uno se han definido los países que usaremos en el primer combo, estos son cinco países, pero pudiese ser cualquier número.
En el paso dos he definido los estados de cada país, es importante mencionar que la relación se está haciendo por la posición en los arreglos, debemos tener esto en mente para escribir lo siguiente:
$id = isset($_POST['id'])?$_POST['id']:-1; //step 1
if($id > -1){ //step 2
//show states
echo toJSON($states[$id]); //step 3
}else{
//show contries
echo toJSON($countries); //step 4
}
En el paso uno se recoge el parámetro “id”, primero verificamos que exista, si no ha sido enviado le asignamos a la variable id un “-1”.
En el paso dos verificamos que el “id” sea mayor que “-1”, esto nos dice que nuestra aplicación está solicitando los estados de un país, la variable “id” debe tener la posición del país solicitado por lo tanto aquí decidimos lo que mostraremos, países o estados.
El paso tres es ejecutado si la variable “id” contenía el índice del país seleccionado, por lo tanto desplegamos los estados del índice solicitado.
El paso cuatro solamente se ejecuta si “id” es menor o igual a -1, esto nos dice que la aplicación ha solicitado los países.
Puedes ver que se está invocando a la función “toJSON” la cual definiremos a continuación:
function toJSON($array){
$data=array(); $i=0; //step 1
$total = count($array);
foreach($array as $key=>$value){ //step 2
array_push($data,array(
'value'=>$i++, //step 3
'label'=>$value
));
}
return json_encode(array( //step 4
'total'=>$total,
'data'=>$data
));
}
El propósito de esta función es crear el JSON que enviaremos a los combos.
En el paso uno creamos dos variables, “data” e “i”, en la variable “data” iremos almacenando cada país o estado que desplegaremos en los combos, la variable “i” es muy importante ya que la usaremos para hacer la relación entre los combos, en el paso tres se explicará esto.
En el paso dos creamos un ciclo que recorra todo el arreglo que recibimos como parámetro, en este arreglo se encuentra la información a desplegar en los combos.
En el paso tres estamos almacenando en la variable “data” cada elemento del arreglo, puedes ver que se está creando un arreglo con dos propiedades “value” y “label”, estas propiedades serán usadas por el combo para su buen funcionamiento, a la propiedad “value” se le asigna el valor de “i”, este valor es el que enviaremos como parámetro para solicitar los estados del país seleccionado, la propiedad “label” simplemente es el texto que desplegará cada opción del combo.
En el paso cuatro regresamos en formato JSON la información recolectada anteriormente.
Creación de los JsonStore
Una vez definida la información a desplegar podemos realizar los combos que usaremos, ya sabemos que los combos utilizan un Store para manipular la información que muestran. En el material de apoyo que descargaste al inicio del tutorial viene un archivo JS (linked-cmb.js) vamos a editarlo y dentro de la función “getStore” escribiremos lo siguiente:
getStore: function(){
var store = new Ext.data.JsonStore({
url:'linked-cmb.php',
root:'data',
fields: ['value','label']
});
return store;
}
Aquí solamente creamos un JsonStore, con los campos que definimos en el servidor, el código anterior deberíamos poder entenderlo pues lo hemos usado en varias ocasiones, lo que sí debo mencionar es que he decidido crear una función que me genere un Store porque necesito dos iguales, por lo tanto para no reescribir dos veces el mismo código, simplemente creé una función que me los genere las veces que sean necesarios.
Creación de los ComboBox dependientes
En el paso anterior creamos una función que genera un JsonStore, ahora vamos a crear dos de estos para usarlos con cada uno de los combos:
this.countryStore = this.getStore(); this.stateStore = this.getStore();
El combo que desplegará los países será de la siguiente manera:
this.countryCmb = new Ext.form.ComboBox({
store: this.countryStore,
id: 'country',
valueField: 'value',
displayField: 'label',
triggerAction: 'all',
emptyText: 'Select a Country',
fieldLabel: 'Country'
});
Aquí no hay nada complicado, solamente una típica configuración de un ComboBox, lo siguiente que debemos hacer es crear el combo que va a desplegar los estados del país seleccionado.
this.stateCmb = new Ext.form.ComboBox({
store: this.stateStore,
disabled: true, //Step 1
id: 'state',
valueField: 'value',
displayField: 'label',
triggerAction: 'all',
mode: 'local', //Step 2
emptyText: 'Select a Contry first',
fieldLabel: 'State'
});
Esta configuración tiene algunas diferencias con respecto a la anterior, estas diferencias son muy importantes y a continuación explico la razón:
En el paso uno estamos deshabilitando el combo, de esta manera forzamos a que el usuario seleccione primero el país, este paso es opcional pero mejora la usabilidad asegurándonos que el usuario no cometa errores en la captura.
El paso dos es muy importante, si no asignamos esta configuración tendremos un comportamiento extraño, ya que al asignarle “mode: ‘local’” nos aseguramos que no haya peticiones Ajax al servidor cuando se expanda al desplegar sus opciones, sino que las despliegue de manera “local”.
Desplegarlos en una ventana
Hasta ahora hemos escrito código pero todavía no se ve nada en la pantalla, es hora de renderizar los componentes, para este ejemplo utilizaré una ventana de la siguiente manera:
this.window = new Ext.Window({
title: 'Linked ComboBox',
layout:'form',
width:300,
height:200,
bodyStyle: 'padding:5px;background-color:#fff',
items: [this.countryCmb,this.stateCmb]
});
this.window.show();
Creación de los ComboBox a utilizar
Agregando el “listener” adecuado
Hasta este punto podemos ver los combos, el combo de países despliega su información correctamente pero el combo de estados esta deshabilitado y no podemos hacer nada con él.
Para poder interactuar con los componentes, necesitamos agregar un “listener” al primer combo, para que cuando éste se seleccione, habilite al combo de estados y cargue la información adecuada.
this.countryCmb.on('select',function(cmb,record,index){ //step 1
this.stateCmb.enable(); //step 2
this.stateCmb.clearValue(); //step 3
this.stateStore.load({ //step 4
params:{
id:record.get('value') //step 5
}
});
},this);
En el paso uno le agregamos un “listener” al evento “select”, este evento se dispara cuando el usuario selecciona una opción del combo, la función recibe tres parámetros: el combo, el record y el índice que ha sido seleccionado.
En el paso dos solamente habilitamos el combo de estados.
En el paso tres limpiamos el valor del combo de estados, esto permitirá que si el usuario ha seleccionado anteriormente un estado, cuando se carguen nuevos estados se limpiará el valor anterior.
En el paso cuatro estamos recargando la información del Store de estados con Ajax.
En el paso cinco estamos enviando el parámetro “id” con el cual el servidor decidirá cuales estados regresar.
Combos dependientes
Conclusión
Siguiendo los pasos de esta tutorial podemos crear combos dependientes de los niveles que necesitemos, solamente necesitamos asignar un “listener” al evento “select” del combo necesario y dentro de este “listener” recargar el store del combo relacionado.
No olvides seguirnos en Twitter (@quizzpot) para estar al tanto de los nuevos tutoriales que publicamos, recuerda que cada vez los temas serán más complejos; de igual manera no te olvides de dejar tus dudas o sugerencias en los comentarios.







Hola:
La verdad soy nueva en esto de ExtJs y la verdad estos tutoriales me han servido demasiado; y sobretodo por q estan demasiado explicados..
Y asi para principiantes como yo;; es mas fácil aprender…
Gracias…
Siempre estoy pendiente de nuevos tutoriales…