Laboratorio: carga de combos
Ayer nos preguntaban cómo cargar combos según lo que se seleccione en otro combo, y aunque no me quedó muy claro la duda que tenÃa, pues para intentar ayudarle, voy a explicar cómo hacerlo mediante tres posibilidades.
Primeramente explicaremos cómo hacerlo mediante el uso de iframes ocultos. SÃ, no es nada web 2.0, pero no a todo el mundo se le da bien el desarrollo web, o no le gusta el uso de Ajax, o simplemente, como me pasa a mÃ, no nos dejan usar Ajax en los desarrollos del cliente (¡vete a saber por qué!).
Después lo haremos mediante Ajax (¡viva la web 2.0!), pero instanciando nosotros mismos el objeto XMLHttpRequest, para que los conceptos de Ajax no se pierdan dentro del uso de librerÃas, es importante conocer la base para luego usar una librerÃa que te lo haga todo más fácil.
Y por último, ya no solo en plan web 2.0, sino en plan lo último de lo último, lo haremos usando la librerÃa Prototype. Que la verdad sea dicha, no se trata de reinventar la rueda.
Antes de nada, explicar el proceso conjunto que tienen los tres modos. Existen dos combos (combo1 y combo2), de los cuales el primero contiene una información estática y el segundo se cargará según lo que se seleccione en el primer combo. Para ello el segundo combo estará vacio inicialmente y el primer combo llamará a la función carga cuando se modifique el valor.
<select id="combo1" onchange="carga(this.value)">
<option value=""></option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
<option value="E">E</option>
</select>
<select id="combo2">
<option value="">Vacio</option>
</select>
Iframe
Debe existir un iframe oculto en el cual se cargará el resultado de la llamada a un script PHP cuando se modifique el valor del primer combo. Este script PHP devolverá un Javascript que modificará el valor del segundo combo.
<iframe id="oculto" src="" style="display:none"></iframe>
<script type="text/javascript">
var datos = new Array();
<?php
$val = $_GET["val"];
for ($i=1; $i<=5; $i++) {
?>
datos[datos.length] = '<?php echo $val.$i; ?>';
<?php
}
?>
var obj = parent.document.getElementById("combo2");
for (var i=0; i<obj.options.length; i++) {
obj.removeChild(obj.firstChild);
}
for (var i=0; i<datos.length; i++) {
var elem = datos[i];
obj.options[i] = new Option(elem);
}
</script>
Ajax
En este caso vamos a crearnos una instancia del objeto XMLHttpRequest y realizaremos una llamada Ajax a un script PHP que nos devolverá un XML con los nuevos datos del combo. Una vez recibidos, los recorreremos para modificar el segundo combo.
function ajaxobj() {
try {
_ajaxobj = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
_ajaxobj = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
_ajaxobj = false;
}
}
if (!_ajaxobj && typeof XMLHttpRequest!='undefined') {
_ajaxobj = new XMLHttpRequest();
}
return _ajaxobj;
}
function carga(val) {
var ajax = ajaxobj();
ajax.open("POST", "ajax.php", true);
ajax.onreadystatechange=function() {
if (ajax.readyState==4) {
var datos = (ajax.responseXML).firstChild;
var obj = document.getElementById("combo2");
for (var i=0; i<obj.options.length; i++) {
obj.removeChild(obj.firstChild);
}
for (var i=0; i<datos.childNodes.length; i++) {
var elem = datos.childNodes[i].firstChild.data;
obj.options[i] = new Option(elem);
}
}
}
ajax.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
ajax.send("&val="+val);
}
<?php
$val = $_POST["val"];
$xml .= '<datos>';
for ($i=1; $i<=5; $i++) {
$xml .= '<valor>'.$val.$i.'</valor>';
}
$xml .= '</datos>';
header('Content-type: text/xml');
echo $xml;
?>
Prototype
Realizarle mediante Prototype es lo mismo que en el ejemplo anterior, salvo que en vez de crearnos la instancia del objeto XHR, usaremos la funcionalidad que nos ofrece Prototype. Por eso el script PHP será el mismo.
<script type="text/javascript" src="prototype-1.4.0.js"></script>
function carga(val) {
var myAjax = new Ajax.Request('ajax.php',
{
method: 'post',
parameters: 'val='+val,
onComplete: modificaCombo
});
}
function modificaCombo(req) {
var datos = (req.responseXML).firstChild;
var obj = $("combo2");
for (var i=0; i<obj.options.length; i++) {
obj.removeChild(obj.firstChild);
}
for (var i=0; i<datos.childNodes.length; i++) {
var elem = datos.childNodes[i].firstChild.data;
obj.options[i] = new Option(elem);
}
}