Aprendiendo Ext JS 3

Combo box cargados local y remotamente (Ajax) Más videos

Descripción del tema

El día de hoy vamos a hablar de un componente que es muy completo: el ComboBox. Veremos cómo configurar un Combo Box de manera local y de manera remota. Describiremos algunas de sus propiedades en la configuración, crearemos un plantilla para que nuestro Combo Box tenga un formato agradable, y al final daremos un recorrido por las diferentes variaciones del Combo Box que nos ofrece ExtJS, por ejemplo el TimeField.

Material de apoyo

Para poder continuar necesitamos descargar el material de apoyo. Recuerda que este tutorial pertenece a la parte de formularios, y al final del tutorial agregaremos nuestro ComboBox al formulario pero para evitar algunas confusiones haremos este tutorial en un archivo diferente.

Empaquetando el tutorial.

Procedemos a empaquetar nuestro código.
Ext.ns('com.quizzpot.tutorial');

Ext.BLANK_IMAGE_URL = '../ext-3.0/resources/images/default/s.gif';

com.quizzpot.tutorial. ComboBoxTutorial= {
	init: function(){
		//aqui va el codigo del tutorial	
       }
}
Ext.onReady(com.quizzpot.tutorial. ComboBoxTutorial.init,com.quizzpot.tutorial. ComboBoxTutorial);

Ventana

A continuación vamos a crear una ventana que alojará nuestros diferentes tipos de ComboBox. Esta ventana nos sirve para visualizar nuestros distintos ComboBoxes que crearemos en este tutorial.
var win=new Ext.Window({
	title: 'ComboBox example',
	bodyStyle:'padding: 10px',		//alejamos los componentes de los bordes
	width:400,
	height:360,			
	layout:'form'					//tipo de organización de los componentes
});
win.show();
Del código anterior podemos resaltar la propiedad "layout:'form'", que para una ventana, el layout por defecto es el "fit", por lo tanto sobre escribimos la propiedad para mostrar los componentes distribuidos como un formulario.
Ventana

Ventana que contendrá los ComboBox

ComboBox Local

Una vez creada nuestra ventana ahora vamos a crear nuestros ComboBoxes; lo primero que necesitamos son los datos que se cargarán en nuestro ComboBox, la manera más simple de cargar datos en nuestro ComboBox es mediante el uso de un arreglo de datos.
var data=['Code Igniter','Cake Php','Symfony','Zend'];

var comboLocal =new Ext.form.ComboBox({
	fieldLabel:'Frameworks PHP',
	name:'cmb-data',
	forceSelection:true,
	store:data,
	emptyText:'Select a framework...',
	triggerAction: 'all',
	//hideTrigger:true,
	editable:false,
	//minChars:3					
});
El código anterior genera un ComboBox, con datos correspondientes a algunos Frameworks existentes de PHP en el mercado. Vamos a ver el significado de las propiedades con las que configuramos nuestro ComboBox: forceSelection: esta opción obliga al usuario a seleccionar un valor del combo, esto es independiente del tipo de validación allowBlank, que discutiremos en un tema posterior. store: es la fuente de datos que nuestro combo mostrará, ya hemos hablado sobre este componente. emptyText: es el texto que se muestra cuando en nuestro combo no se ha seleccionado nada. triggerAction: esta opción le indica al combo que siempre muestre todos los datos de su store, cuando utilizamos un store remoto aquí le pondríamos el query que se mandaría a nuestra fuente de datos remota. editable: el combo no puede ser editado, es decir no se le puede escribir algún valor. hideTrigger: poniendo esta propiedad en true hacemos que el combo aparezca sin el iconito de la flecha hacia abajo (“disparador”). minChars: nos indica cuantos caracteres debemos de escribir antes de que el combo empiece a mostrar información, en nuestro caso debemos comentar la propiedad editable y no comentar la propiedad minChars para ver su funcionalidad. Ahora lo agregamos a nuestra ventana:
var win=new Ext.Window({
	bodyStyle:'padding: 10px',//alejamos los componentes de los bordes
	width:400,
	height:360,
	items: comboLocal, //agregamos el combo a la ventana
	layout:'form'		//tipo de organización de los componentes
});
win.show();
Combo sencillo

Un combo cargado con información local

ComboBox Remoto

Ahora vamos a crear un combo que cargaremos con datos de manera remota utilizando Ajax. En esta ocasión usaremos PHP, pero como ya sabemos podemos utilizar cualquier otro lenguaje servidor. En el ComboBox remoto utilizaremos para nuestra fuente de datos un store de tipo JSON, este componente no se va a detallar debido a que en un tutorial anterior se habló sobre dicho componente. El código JS queda de la siguiente manera:
//se crea el store
var store= new Ext.data.JsonStore({
		url:'combo.php',
		root: 'data',					
		totalProperty: 'num',
		fields: [
			{name:'name', type: 'string'},
			{name:'desc', type: 'string'},
			{name:'logo', type: 'string'},
		]
});

//se crea el combo asignandole el store
var comboRemote=new Ext.form.ComboBox({
	fieldLabel:'Data Base',
	name:'cmb-DBs',
	forceSelection: true,
	store: store, //asignandole el store
	emptyText:'pick one DB...',
	triggerAction: 'all',			
	editable:false,
	displayField:'name',
        valueField: 'name'	
});
Como podemos observar en las propiedades de nuestro combo le agregamos la propiedad displayField, con esta propiedad le decimos al ComboBox que información mostrar, en este caso nos va a mostrar solo los datos ‘name’ y utilizando la propiedad "valueField" le especificamos cual campo del store utilizar como "value", puede ser un ID numérico pero en este caso utilizamos el nombre. Cuando usamos un store remoto podemos utilizar paginación con la propiedad ‘pageSize’, esta propiedad nos permite configurar el número de datos que queremos mostrar en nuestro combo. Por último es necesario agregar el combo que acabamos de crear a la ventana, de la siguiente manera:
var win=new Ext.Window({
	title: 'ComboBox example',
	bodyStyle:'padding: 10px',		//alejamos los componentes de los bordes
	width:400,
	height:360,
	items: [comboLocal,comboRemote],//se agrega el combo remoto
	layout:'form'					//tipo de organización de los componentes
});
win.show();
Combo remoto

Un ComboBox cargado remotamente utilizando Ajax

Mediante código PHP vamos a exponer la información que mostrará el combo, esta información puede salir de una base de datos, o un servicio web, para poner las cosas simples y entendibles la información esta "hardcode" en arreglos.
<?php
	$dataDB = array(
				array(
					"name"=>"MySQL",
					"desc"=>"The world's most popular open source database",	
					"logo"=>"mysql.png"
				),
				array(
					"name"=>"PostgreSQL",
					"desc"=>"The world's advanced open source database",					
					"logo"=>"postgresql.png"
				),
				array(
					"name"=>"Oracle",
					"desc"=>"The world's largest enterprise software company",
					"logo"=>"oracle.png"				
				),
	);
	
	$o = array(
			"num"=>count($dataDB),			
			"data"=>$dataDB
		);
	echo json_encode($o);
?>
Nótese que se han definidos los campos que el JsonStore acepta, además mediante la función json_decode se esta generando el JSON a partir de un arreglo de PHP.

Datos con formato

Muy bien ahora vamos a darle formato a nuestra información, ocuparemos la información de nuestro combo remoto, así que empecemos. Vamos a crear un nuevo ComboBox que se cargará con los mismos datos que nos proporciona el PHP, ocupando el mismo store del combo anterior. Para darle formato a nuestro ComboBox ocupamos una plantilla, así que se la vamos a asignar a nuestro nuevo combo mediante una de sus propiedades (“tpl” de "template"). La plantilla está escrita en HTML con un poco de CSS para que la información se presente de una manera más detallada.
var comboRemoteTpl = new Ext.form.ComboBox({
	fieldLabel:'Data Base',
	name:'cmb-Tpl',
	forceSelection:true,
	store:store,
	emptyText:'pick one DB...',
	triggerAction: 'all',
	mode:'remote',
	itemSelector: 'div.search-item',
	tpl: new Ext.XTemplate('<tpl for="."><div class="search-item" style="background-image:url({logo})"><div class="name">{name}</div><div class="desc">{desc}</div></div></tpl>'),						
	displayField:'name'
});
Las propiedades que aparecen ahora son: tpl: le asigna un plantilla a mostrar para cada dato del combo, la plantilla que se crea es una cadena de HTML y con algunos estilos y clases de CSS, en próximos temas se dedicará un tutorial completo para analizar el funcionamiento del objeto "Ext.XTemplate", por ahora solo es importante mencionar que mediante un ciclo se recorre todos los registros del store y va generando la lista de opciones a presentar al usuario. itemSelector: esta propiedad nos indica cual va a ser la propiedad del DOM que dispara al evento select de nuestro combo. Hasta ahora hemos modificado el markup o HTML de la lista desplegable del combo, lo que falta es darle los estilos necesarios de la siguiente manera:
	.search-item{
		border:1px solid #fff;
		padding:3px;
		background-position:right bottom; 
		background-repeat:no-repeat;
	}
	.desc{	
		padding-right:10px;
	}
	.name{	
		font-size:16px !important;
		color:#000022;	
	}
Combo personalizado

ComboBox personalizado con un template

Una variación del ComboBox

Existe un componente en ExtJs que es una variación del ComboBox este componente se llama TimeField y sirve para mostrar valores respectivos al tiempo. La mayoría de sus propiedades son las mismas que el ComboBox.
var timeField=new Ext.form.TimeField({						
       	fieldLabel: 'Time Field',
       minValue: '4:00',
       maxValue: '23:59',
       increment: 15,
       format:'H:i',
       name:'cb-time'						
});
Combo de tiempo

Un combo con el tiempo

Como podemos ver sin mayor complicación hemos creado un nuevo ComboBox que nos muestra datos en formatos de tiempo. Expliquemos algunas de sus propiedades. minValue: es el valor mínimo que va a mostrar nuestro campo. maxValue: el valor máximo que mostrará. increment: el tamaño del incremento de los valores de nuestro campo. format: el formato en el que se mostrará nuestros valores de tiempo.

Conclusiones

El día de hoy hemos visto un componente muy completo llamado ComboBox, este componente tiene muchos diferente tipos de configuraciones que lo hacen un componente muy recurrido en todo tipo de aplicaciones con Ext JS. Para poder ver más de las bondades de este componente no olviden consultar el API de ExtJS. Si tienes alguna sugerencia no olvides dejar un comentario o inscríbete en el Foro para aclarar tus dudas.

Te gustaría recibir más tutoriales como este en tu correo?

Este tutorial pertenece al curso Aprendiendo Ext JS 3, te recomiendo revises el resto de los tutoriales ya que están en secuencia de menor a mayor complejidad.

Si deseas recibir más tutoriales como este en tu correo te recomiendo registrarte al curso, si ya eres miembro solo identifícate y registrate al curso, si no eres miembro te puedes registrar gratuitamente!

Si no gustas registrarte en este momento no es necesario! Aún así puedes recibir los nuevos tutoriales en tu correo! Jamás te enviaremos Spam y puedes cancelar tu suscripción en cualquier momento.

¿Olvidaste tu contraseña?

36Comentarios

  • Avatar-1 Crysfel 10/06/2009

    Este tutorial fué realizado por Jose Armando (<a href="http://twitter.com/manduks" rel="nofollow">@manduks</a>) pronto acabaremos el curso con la ayuda de todos ustedes. :D

    • Avatar-7 DrMartin 14/06/2009

      Maravilloso ejemplo, exactamente estaba buscando como hacer este tipo de combos en ExtJS. ¡gracias! :D

      • Avatar-1 jose 15/06/2009

        Buenas, crysfel como se pondria un title a una windows desde fuera de la creación de la ventana. Sigue así, lo que haces es una gran ayuda para todos, gracias.

        • Avatar-4 manduks 15/06/2009

          hola jose, bueno todos los paneles tienen al metodo setTitle("Nuevo Titulo"). :), te recomiendo que te des de alta en los foros donde encontraras respuestas a tus dudas mas rapido y con mayor detalle.

          • Avatar-8 Robert 04/08/2009

            Muy bien, solo que segui los pasos y la propiedad background-repeat:no-repeat; solo funciona para el elemento seleccionado, para los demas me muestra el background repetido :s Saludos

            • Avatar-8 Isaac 05/08/2009

              como hago para obtener el value de un combox,"solo es value",no el text

              • Avatar-1 Crysfel 05/08/2009

                Utiliza el método "cmb.getValue()" ;)

                • Avatar-9 Angélica M 26/02/2014

                  Hola, cuando utilizo el getValue() en el timefield me guarda toda la fecha: 2008-01-01T09:00:00 cuando en realidad necesito la hora, que metodo debería usar!! URGENTE plis.

                  • Avatar-10 Crysfel Villa 26/02/2014

                    Hola Angélica. El método getValue() te regresa un objeto de tipo Date, una vez que tienes el Date puedes sacar la hora usando el método val.getHours() y val.getMinutes() Saludos

                • Avatar-8 Leonid 10/09/2009

                  Hola, muy bueno e interesante tu tutorial. Y como deberia hacer cuando quiero cargar un combo tomando como base la informacion de un combo anterior. Algo asi como un combo de paises y un segundo de ciudades del pais seleccionado

                  • Avatar-8 Elías Manchón 11/09/2009

                    Hice la versión con Mapas en JSP. Saludos.

                    • Avatar-4 Gustavo 15/09/2009

                      Buenisimo ejemplo, pero llegue hasta aca para aprender a hacer un combo con suggestion box, o sea, que se autocomplete. por ejemplo, una lista de paises, si tecleo a, me saldrian todos los paises que empiezan con a, si sigo tecleando hasta ar->se muestren los paises que empiezen con ar y asi sucesivamente. Gracias, buenisimo blog!

                      • Avatar-3 cfontes 22/09/2009

                        Estoy manejando un combo el cual lleno con los estados de la republica mexicana, quisiera saber como le hago para que por default me aparezca el nombre del primer estado de la lista en vez de aparecer en blanco en espera de una seleccion.

                        • Avatar-7 Rafael 08/03/2010

                          en ie este ejemplo no funciona, pero es por el ultimo combo y en la version que tengo de ie no me deja instalar el iedeveloper tool bar si encuentro el problema o alguien lo encuentra por favor informelo

                          • Avatar-12 Rafael 08/03/2010

                            perdon, es el antepenultimo combo, version de ie 7.0.0.573.13

                            • Avatar-6 jose 27/07/2010

                              hola oye como agrando el largo del jcombox?

                              • Avatar-12 Crysfel 28/07/2010

                                Usa la propiedad "width". Saludos

                                • Avatar-6 Pild 20/08/2010

                                  Hola Crysfel, estoy trabajando con kumbia php, no se si lo has utilizado, estoy generando el metodo que me devuelve el arreglo en el controlador. pero no se llena el combo, que puede hacer?

                                  • Avatar-12 jamc 27/08/2010

                                    Hola, excelentes tutoriales amigo, la verdad son de mucha ayuda; solo una corrección sobre la redacción de este tutorial, despues del código PHP, en la redacción colocas esto "...además mediante la función json_decode se esta generando el JSON a partir..." debe decir "además mediante la función json_encode se esta generando el JSON a partir "

                                    • Avatar-9 Crysfel 30/08/2010

                                      Gracias por la observación, ya lo he corregido.

                                      • Avatar-10 franshow 18/10/2010

                                        Muy buen ejemplo!! , Extjs trabaja con combobox muy completos. una de las grandes polemicas al momento de crear un formulario, es la rapidez para poder llenarlo, sin embargo en el caso de los combobox en modo remoto no permite el parametro typeAhead lo que hace que el formulario tenga lentitud al llenarlo

                                        • Avatar-9 Nakú 26/10/2010

                                          Saludos Crysfel antes que nada muy buenos tutoriales felicidades, pero ahí va la duda, y es que este ejemplo si me corre perfectamente en cualquier navegador menos en firefox en especial solo lo he corrido en la versión 3.6.11, realizando las pruebas en el servidor de mi casa, todo al parecer está bien pero el combo no carga los datos = en el caso del tutorial de los combos dependientes, de tu experiencia no sabrás algún caso el porque se da esta situación, o alguna idea que me puedas ayudar?, de antemano mil gracias, y sigue así mejorando cada vez más, saludos.

                                          • Avatar-12 Cristian 18/01/2011

                                            Hola, master! Muy buena data. Tengo una consulta: Es posible configurar el combo para que cada vez que se dé click sobre la flecha para desplegarlo se actualicen los datos de manera automática? Saludos!!!

                                            • Avatar-11 HtDreams 15/02/2011

                                              Muchas gracias por la información Llevo un buen rato peleándome para conseguir un combo local (traducción de lo que sería un simple select) y después de muchos ejemplos y crear arraystores, tu solución es perfecta, y no la vi documentada... asignar el array de javascript como store, genial :-) Lo bueno es que si tenemos un array multidimensional ext-js ya procesa solo los pares value - text

                                              • Avatar-1 miguel 30/04/2011

                                                hola, gracias por tus posts, me estan ayudando mucho. Te consulto porque tengo un problema, con un combo, uso Struts y el plugin de JSON para convertir a json mis datos. tengo este combo { xtype: 'combo', x: 80, y: 10, width: 240, mode: 'remote', emptyText: 'Elige un concepto', store: new Ext.data.JsonStore({ url: '../getDatosAlumno', root: 'listaConceptos', autoLoad: true, fields: ['clave','concepto','importe'] }), name: 'cmbConceptos', forceSelection: true, editable: false, displayField: 'concepto', valueField: 'clave', id: 'idCmbConceptos' } y esta es la respuesta que me da el servidor: {"listaConceptos":[["1","Colegiatura",100.0],["2","Cursos",200.0]]} Aparentemente todo esta bien, y ya intente de todas las formas que encontre, y ese combo no me esta cargando los datos, te agradeceria mucho que des una mano, Gracias y un saludo.

                                                • Avatar-2 Luis 15/05/2011

                                                  Gracias por el tutorial, excelente, pero dime una cosita, como hago para que el combo este seteado para un dato por default Gracias por instruirme Saludos cordiales

                                                  • Avatar-7 Rafa 26/05/2011

                                                    Hey Crysfel muy bueno la verdad excelente, solo que tengo una duda como le hago para cachar el "valueField" del combo con las imagenes?, y aque solo recibo el texto que se muestra en el imput "displayField", un saludo, esperando respuesta. Luis, esto con php puedes darle un valor por default Ext.getCmp('id_del_combo').setValue("");

                                                    • Avatar-6 Rafa 26/05/2011

                                                      ja! Luis el sistema me elimino el codigo de php en el comentario, pero seria de esta forma Ext.getCmp(‘id_del_combo’).setValue(“texto que muestra el combo”); saludos!

                                                      • Avatar-1 yudiel 09/06/2011

                                                        quisiera saber si es posible como hago para que un combo se ajuste automáticamente al tamaño de la informacion que contiene eje si el combo tiene que cargar Cuba Venezuela República Dominicana entonces el combo debe coger como tamaño el de republica dominicana

                                                        • Avatar-12 Julio 16/07/2011

                                                          Buen post Crysfel. Tengo una consulta, en un combo con autocompletaado, hay alguna posibilidad de que se pueda filtrar por cualquier caracter, no necesariamente por la primera letra. Saludos desde Perú.

                                                          • Avatar-3 Jorenilson 17/07/2011

                                                            Como faço isso em asp????

                                                            • Avatar-8 ricardo 10/07/2012

                                                              Hola crys primero que nada felicitaciones por tus portes a muchos nos aclaras varias dudas y nos ayudas con la etapa de aprendizaje. tengo un par de dudas: como hago para que busque en toda la cadena y no solo al incio? puedo resaltar la subcadena encontrada? muchas gracias

                                                              • Avatar-2 Carlos 28/02/2013

                                                                Crysfel, tus tutoriales son excelentes, unicamente quiero hacerte una consulta con respecto a este ejemplo, he hecho todo al pie de la letra pues en una ventana necesito poner un combobox con imagenes, me aparece todo bien, pero cuando le doy el formato, ya no me permite seleccionar las opciones, osea, si aparecen perfectamente, pero ya no se ponen azules para la selección, y en lugar de aparecer la mano normal para seleccion, me aparece una flecha... me estaran fallando los css?

                                                                • Avatar-1 Carlos 28/02/2013

                                                                  Crysfel y amigos, una hora despues de haber publicado el problema, encontre la solución, si a alguie se le presenta un problema similar yo lo arregle asi: La diferencia con el codigo que publica Crysfel aqui, es que mi combobox no parte de una variable, osea var combo= Ext.create... sino que es un xtype... Entonces para que reconociera los campos fue necesario encerrar la configuración formateada en la siguiente estructura: listConfig: { getInnerTpl: function() { return '{nombre}{desc}'; } }, y Voila... funciona fenomeno, gracias por la orientación Crysfel

                                                                  • Avatar-8 Carlos 28/02/2013

                                                                    ummm, se borra alguna información al publicar, la idea es que en el return se ponga la fila formateada que aparece en el cuadro de datos con formato, fila 10, pero sin el tpl: new Ext.XTemplate

                                                                    • Avatar-9 Akiyama Shinichi 11/09/2017

                                                                      Gracias excelente post muy bien explicado, justo lo que buscaba. Saludos!

                                                                      Instructor del curso

                                                                      Crysfel3

                                                                      Autor: Crysfel Villa

                                                                      Es ingeniero de software con más de 7 años de experiencia en desarrollo web.

                                                                      Descarga Código Fuente Ver Demostración

                                                                      Regístrate a este curso

                                                                      Este tutorial pertenece al curso Aprendiendo Ext JS 3, revisa todos los tutoriales que tenemos en este mismo curso ya que están en secuencia y van de lo más sencillo a lo más complicado.

                                                                      Tendrás acceso a descargar los videos, códigos y material adicional.

                                                                      Podrás resolver los ejercicios incluidos en el curso así como los Quizzes.

                                                                      Llevarás un registro de tu avance.