Hace pocos días, vimos la forma de hacer un sencillo AJAX utilizando jQuery, pero nos limitamos a hacer que nuestro documento leyera de forma dinámica una porción de texto e imágenes. Hoy, subiremos un escalón y le daremos una mayor utilidad a esta tecnología que recién empezamos a aprender.
Cuando me iniciaban (porque admito que fue contra mi voluntad
) en el uso de jQuery, me vi en la imperiosa necesidad de hacer que cuando seleccionaba un elemento de una lista desplegable A, automáticamente cambiaran los elementos de otra lista B. Fue un día de trabajo dedicado a buscar y probar plugins que tuvieran esa funcionalidad, pero al final lo conseguí y con el asesoramiento de un compañero de trabajo todo quedó según los requerimientos y especificaciones iniciales.
Tiempo después, lo recuerdo hasta con un poco de lástima por mí mismo, pues si me hubiera dedicado un poco antes a aprender como utilizar jQuery, no habría pasado por ese apuro y todo hubiera terminado en cuestión de una hora o dos. Ahora, procedo a explicar los pormenores del asunto y espero que el lector comprenda no sólo su sencillez sino también la lógica que conlleva. Vamos allá.
En el documento emisor (index.php) colocamos las listas desplegables (combobox) que no representan ningún problema:
Categorías:
<select id="categorias">
<option value="0">Seleccione una categoría</option>
<option value="1">Autos</option>
<option value="2">Películas</option>
<option value="3">Deportes</option>
</select>
Sub-categorías:
<select id="subcategorias">
<option value="0">Seleccione una categoría</option>
</select>
El segundo combo, como puede observarse, queda vacío, pues sera llenado dinámicamente al seleccionar un valor del primero. Con en el tutorial anterior ya utlizamos $.get para hacer el AJAX, esta vez no entraremos en un análisis de su funcionamiento, pero si en los de su aplicación para el problema que nos ocupa hoy.
$(document).ready(function(){
$('#categorias').change(function(){
var categoria = $('#categorias').val();
$.get('database.php', { cat: categoria }, function(options){
$('#subcategorias').html(options);
});
});
});
Vamos explicando rápidamente esta porción de código línea por línea:
- El jQuery se ejecutará solo cuando todo el documento haya terminado de cargar.
- Aquí ya hay una diferencia sustancial respecto al ejemplo anterior, pues cambiamos el evento
click, por el eventochange. Esto significa que el código interno solo será ejecutado, al cambiar el valor del primer combo. Es decir que si hacemos clic para abrir la lista y luego otro clic para cerrarla pero no le cambiamos la opción que aparece seleccionada, no pasará absolutamente nada. Para que funcione, el elemento seleccionado del primer combobox debe cambiar. - En la tercer línea, le asignamos el valor del primer combobox a una variable llamada
categoria. Para los que se inician en desarrollo web, les recordamos que el valor del combobox no es el texto que el usuario puede ver, sino elvaluedeloption. Según nuestro ejemplo, si el usuario selecciona “Autos”, el valor de la variable será de 1, mientras que al escoger “Deportes” será el 3. Este dato es muy importante pues al hacer el AJAX es necesario que el documento receptor sepa que contenido tiene que devolver (según veremos unas líneas más adelante). - Luego, hacemos la llamada al documento receptor, pero si comparamos con con el ejemplo de la lección anterior, veremos que ahora hay algo nuevo: entre la URL del documento y la función de respuesta encontramos
{ cat: categoria },. Esto es la “data”, o bien, el conjunto de datos que enviamos al documento receptor en forma de pares ordenados. Esto merece una buena explicación:- La definición de
$.get, es la siguiente:$.get( url, [data], [callback], [type] ), según podemos encontrar en la documentación oficial. Como no enseñan los libros, los parámetros entre corchetes ([]) son opcionales, y si no vamos a incluir alguno, solo debemos respetar el orden de la sintaxis. Por ello, en el ejemplo anterior pudimos omitir la “data” sin mayores problemas, y por el momento seguimos sin utilizar el “type”, que explicaremos en futuras lecciones. - La “data” debe escribirse entre llaves (
{}). Anteriormente mencionaba que adopta la forma de pares ordenados, y me refiero a que asignamos valores (de nuestro javascript) a las variables que recibirá PHP. Por ejemplo si nuestra “data” es{ nombre: name, apellido: lastname }y los valores denameylastnameson “Juan” y “Pérez” rspectivamente, esto equivale a escribir en la URL?nombre=Juan&apellido=Pérez, lo cual es bien conocido para quien programa en PHP.
- La definición de
- Finalmente, en la quinta línea, asignamos la respuesta de nuestro AJAX, como HTML interno del segundo combobox. Es decir que el
optionque le colocamos de forma predeterminada, será reemplazado por lo que venga del documento receptor.
Hasta aquí el jQuery, y como podemos observar, una vez que lo comprendemos bien, no es nada del otro mundo. Sin embargo, aún no está terminada la funcionalidad. Es obvio entonces que parte de la magia del AJAX ocurre también del lado del documento receptor (database.php). Empecemos con un pequeño arreglo. Para referencia de arreglos, ver el tutorial que elMaxx presentó sobre el tema. Admito que estos datos en lugar de un simple arreglo deberían venir de una base de datos (de allí el nombre del documento receptor), pero debido a la simplicidad del ejemplo, no vamos a entrar esos temas todavía. Los que trabajan con bases de datos, ya tendrán una idea de como aprovecharlas para aplicarlas en estos combos encadenados, mientras que los que nunca las han trabajado, no tienen de que preocuparse
.
$subcategorias = array(
// clave => valor
'1' => array(
'101' => 'Ferrari',
'102' => 'Porsche',
'103' => 'Jaguar'
),
'2' => array(
'201' => 'Starwars',
'202' => 'Terminator',
'203' => 'Spiderman',
'204' => 'The Godfather',
'205' => 'Robocop'
),
'3' => array(
'301' => 'Fútbol',
'302' => 'Beisbol',
'303' => 'Tenis'
)
);
Como puede observarse, este arreglo consta de tres elementos numerados como 1, 2 y 3 respectivamente, al igual que las opciones de nuestro primer combobox, lo cual no es una coincidencia. Precisamente son estos valores los que nos servirán para obtener la información que debe llenar la segunda lista desplegable. Cada elemento del arreglo, es un sub-arreglo que consta de valores, cada uno identificado por un nombre: por ejemplo, para la posición 1 que corresponde a marca, encontramos el valor “Ferrari”, con la clave 101. Ya con estos datos procedamos a hacer que nuestro PHP construya los contenidos del segundo combobox.
$categoria = $_GET['cat'];
$respuesta = '';
if ($categoria)
foreach($subcategorias[$categoria] as $clave => $valor)
$respuesta .= '<option value="'.$clave.'">'.$valor.'</option>';
else
$respuesta = '<option value="0">Seleccione una categoría</option>';
echo $respuesta;
Nuevamente, tenemos un segmento de código que merece ser comentado línea por línea.
- Asignamos a la variable
$categorialo que venga en el parámetro “cat”. Esto es posible gracias a la data enviada por jQuery con{ cat: categoria }. Lo recibimos con$_GET, porque para nuestro AJAX utilizamos$.get, así que los curiosos pueden probar a enviar con$.posty recibir con$_POST. - La segunda línea, incluye uno truco común en programación que a su vez se considera como una buena práctica. Explico: nuestro jQuery solamente puede enviar los valores 0, 1, 2 y 3, que son los que contiene el primer combobox. Ya sabemos cuales corresponden a las categorías, y que el cero solo representa el mensaje “Seleccione una categoría” y por lo tanto no debe alterar la segunda lista desplegable. Pues bien, sabemos que en PHP el valor cero equivale a FALSO y cualquier otro valor (excepto NULL) es VERDADERO. Por lo tanto, si el valor enviado es cero, es decir falso, podemos comprobarlo con
if ($categoria). Es una forma abreviada de averiguar si la variable contiene un valor que no sea cero, pues simplemente preguntamos ¿es veradero?. - Si es verdadero, significa que es uno de los valores 1, 2 o 3. Supongamos que es 3, entonces acá hacemos un barrido del arreglo
$subcategoriasen la posición$categoria(es decir 3). De nuevo, si alguien no lo tiene claro, ver el tutorial de arreglos en PHP. - Teniendo la clave y el valor de nuestro arreglo de deportes (el número 3), utilizamos estos datos para construir un
<option>por cada elemento mediande unforeach. - Los observadores habrán notado que estamos asignando a la variable
$respuestacon “.=“. Esto es la forma corte de expresar:
$respuesta = $respuesta.'<option...'. - Y si el valor de la categoría es cero…
- …”reconstruimos” el <option> predeterminado del segundo combobox.
- Finalmente, imprimimos la respuesta.
En la próxima lección, implementaremos el uso del JSON y la forma de aprovecharlo al momento de obtener una respuesta.


#1 by harryson gonzalez on 18/Oct/2009
la verdad estaba buscando como colocar combobox concatenados, me ha servido.
lo implementare pero no con un array si no con la consulta a la base.
muchas gracias
#2 by Attakinsky on 19/Oct/2009
Gracias por el comentario, es bueno saber que esto le ha servido a alguien. Y sí, como mencionaba en el post, lo ideal es hacerlo con bases de datos.
Agradezco también tu visita.
#3 by david on 21/Nov/2009
quisiera saber si hay formas de utilizar un desplegable que al mismo tiempo sea escribible. Es decir necesito que en la primera linea exista cero y que ese cero se pueda reescribir con un numero de 5 digitos habiendo en este despelgable en la segunda, tercera, cuarta y quinta linea otras opciones con numeros de 4 o 5 digitos. Gracias por su respuesta.
#4 by Attakinsky on 17/Dic/2009
Perdón por el retraso, pero he andado muy desconectado de todo por motivo de trabajo.
En realidad si se puede pero necesitas trabajar mucho jquery. Pistas:
- manejas tus option en un arreglo
- el escribible es un input type=text
- lees el dato y lo metes a tu arreglo
- convertis los elementos de tu arreglo en option y sustituis los anteriores
Es posible que haya un plugin que ya lo haga, busca en internet a ver si encontras algo.
#5 by Attakinsky on 22/Dic/2009
Esto puede servirte: http://javascript.about.com/library/blcombo.htm
#6 by Carlos Andrés on 17/Dic/2009
En IE no funciona pero en firefox corre perfecto… me podria ayudar..
#7 by Attakinsky on 17/Dic/2009
Como dice @guatecham, es probable que sea IE el malo. Pero como desarrollador no es excusa, dejame revisar y publico luego las correcciones correspondientes.
Gracias por el aviso.
#8 by guatecham on 17/Dic/2009
mmmm hay muchas cosas que en IE no funcionan y en firefox, Chrome, Safari, Opera, etc. corre perfecto…
Para mi que lo que esta mal es IE XD
#9 by orlando on 9/Ene/2010
explendido tema esto lo del JQUERY me sirve de mucho yo tambien estoy implementado unos combox encadenados para hacer consulta a mi base de datos de paises regiones y ciudades, con esta explicacion creo q no habra mayor problema en lograrlo,
gracias por el post
#10 by Attakinsky on 9/Ene/2010
Orlando: me alegra mucho haber podido servir de algo. Pronto tendremos acá más material que seguro también será de utilidad.