COMBOS DINÁMICOSAnteriormetne he visto artículos que tocan este tema, pero hasta ahora todos se refieren a PHP, pero ninguno referente a ASP, éste es el motivo del presente artículo, asi que sin mas empecemos.
Supongamos que tenemos una base de datos llamada
AJAX, que contiene dos tablas relacionadas; una de giros comerciales(Giros_Comerciales) y otra de empresas(Empresas) - relacionada con la anterior por un mismo id de giro comercial -. Ahora, supongamos que queremos mostrar un formulario con todos los giros comerciales y que cada vez que seleccionemos un giro distinto se actualice ,dinámicamente, una lista de empresas; pero además esto lo queremos hacer sin estar recargando toda la página, o sea, ocupando AJAX.
Como primer punto debemos crear una página asp donde colocaremos el formulario, incluyendo la lista de giros y de empresas, la cual la llamaremos inicial.asp. La lista de giros la llenaremos desde un prinicpio y la lista de empresas será la que actualizaremos dinámicamente, el código es el siguiente:
(inicial.asp)
<%@LANGUAGE="VBSCRIPT" CODEPAGE="1252"%>
<%
'Línea para indicar el driver a ocupar
'para la conexión a la base de datos
basededatos="Driver={SQL Server};"& _
"Server=LOCALHOST;"& _
"Database=AJAX;"& _
"Uid=sa;"& _
"Pwd=;"
'Objeto para realizar la conexión a la base de datos
set conexion = server.createobject("adodb.Connection")
conexion.open(basededatos)
'Se declara la selección de campos de la base de datos
giro = "SELECT Id, Descripcion FROM Giros_Comerciales ORDER BY Descripcion"
set giros = conexion.execute(giro)
%>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Combos dinámicos con AJAX</title>
</head>
<body>
<!--Se crea el formulario para mostrar los combos-->
<form name="frmCombos" action="combos.asp" method="post">
<label>Giro comercial</label>
<select name="giros_comerciales" id="giros_comerciales">
<option value=""></option>
<%
'Se muestran todos los giros comerciales obtenidos con la consulta
do while not giros.eof
%>
<option value="<%=giros("id")%>"><%=giros("descripcion")%></option>
<%
'Se avanza al siguiente registro
giros.movenext
loop
'Se libera memoria
set giros = nothing
%>
</select>
<p>
<div id="Empresas_Relacionadas">
<label>Empresas</label>
<select name="empresas" id="empresas">
</select>
</div>
</p>
</form>
</body>
</html>
<%
'Se cierra la conexión y se libera memoria
conexion.close()
set conexion = nothing
%>
Lo que hemos hecho es crear la primera lista a partir de los datos de la tabla "giros_comerciales" y dejamos la lista correspondiente a las
empresas vacía y dentro de una capa llamada
Empresas_Relacionadas, esta capa será donde se muestre el contenido que obtendremos tras hacer la petición con AJAX.
Lo siguiente que tenemos que hacer es crear una instancia del objeto
XMLHttpRequest() y una función que nos permita cargar el contenido para la lista de empresas; esta lista estará limitada por alguno de los giros comerciales. Agregando el código necesario, nuestra página se verá de la siguiente forma:
(inicial.asp)
<%@LANGUAGE="VBSCRIPT" CODEPAGE="1252"%>
<%
'Línea para indicar el driver a ocupar
'para la conexión a la base de datos
basededatos="Driver={SQL Server};"& _
"Server=LOCALHOST;"& _
"Database=AJAX;"& _
"Uid=sa;"& _
"Pwd=;"
'Objeto para realizar la conexión a la base de datos
set conexion = server.createobject("adodb.Connection")
conexion.open(basededatos)
'Se declara la selección de campos de la base de datos
giro = "SELECT Id, Descripcion FROM Giros_Comerciales ORDER BY Descripcion"
set giros = conexion.execute(giro)
%>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Combos dinámicos con AJAX</title>
<script>
//Función para crear un objeto XMLHttpRequest
function crearAjax() {
var Ajax
if (window.XMLHttpRequest) { // Intento de crear el objeto para Mozilla, Safari,...
Ajax = new XMLHttpRequest();
if (Ajax.overrideMimeType) {
//Se establece el tipo de contenido para el objeto
//http_request.overrideMimeType('text/xml');
http_request.overrideMimeType('text/html');
}
} else if (window.ActiveXObject) { // IE
try { //Primero se prueba con la mas reciente versión para IE
Ajax = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try { //Si el explorer no esta actualizado se prueba con la versión anterior
Ajax = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!Ajax) {
alert('¡Por favor, actualice su navegador!');
return false;
}
else
{
return Ajax;
}
}
//Función para actualizar el combo para las empresas
function ActualizarEmpresas (pagina, cmbDelimitador, divContenedora)
{
//Se obtiene la referencia del div
//donde se mostrarán los resultados
var contenedor = document.getElementById(divContenedora);
//Se obtiene el valor seleccionado en el combo delimitador
var valdelimitador = document.getElementById(cmbDelimitador)
var x = valdelimitador.value
//Se contruye la url pasando, como parámetro, el valor seleccionado
var url_final = pagina+'?Id='+x
//Se muestra una imagen de espera en la capa contenedora del combo delimitado
contenedor.innerHTML = '<img src="imagenes/cargando.gif" />'
//Se crea un objeto XMLHttpRequest
var objAjax = crearAjax()
objAjax.open("GET", url_final)
objAjax.onreadystatechange = function() {
if (objAjax.readyState == 4) {
//Se escribe el resultado en la capa contenedora
contenedor.innerHTML = objAjax.responseText;
}
}
objAjax.send(null);
}
</script>
</head>
<body>
<!--Se crea el formulario para mostrar los combos-->
<form name="frmCombos" action="combos.asp" method="post">
<label>Giro comercial</label>
<select name="giros_comerciales" id="giros_comerciales">
<option value=""></option>
<%
'Se muestran todos los giros comerciales obtenidos con la consulta
do while not giros.eof
%>
<option value="<%=giros("id")%>"><%=giros("descripcion")%></option>
<%
'Se avanza al siguiente registro
giros.movenext
loop
'Se libera memoria
set giros = nothing
%>
</select>
<p>
<div id="Empresas_Relacionadas">
<label>Empresas</label>
<select name="empresas" id="empresas">
</select>
</div>
</p>
</form>
</body>
</html>
<%
'Se cierra la conexión y se libera memoria
conexion.close()
set conexion = nothing
%>
La función, en javascript,
"ActualizarEmpresas" que hemos creado en este punto, necesita de tres parámetros:
- pagina. Es la URL de la página que obtendrá los datos de las empresas basándose en el filtro de giro comercial
- cmbDelimitador Es el valor de la propiedad "id" de la lista que contiene los giros comerciales
- divContenedora Es el valor de la propiedad "id" de la capa donde se mostrará la lista filtrada de empresas.
Ahora tenemos que agregar la llamada a la función en el evento change de la lista de giros comerciales, para que cada vez que se eliga un giro distinto, la lista de empresas se actualice. Entonces nuestra página
inicial.asp quedará de la siguiente forma:
(inicial.asp)
<%@LANGUAGE="VBSCRIPT" CODEPAGE="1252"%>
<%
'Línea para indicar el driver a ocupar
'para la conexión a la base de datos
basededatos="Driver={SQL Server};"& _
"Server=LOCALHOST;"& _
"Database=AJAX;"& _
"Uid=sa;"& _
"Pwd=;"
'Objeto para realizar la conexión a la base de datos
set conexion = server.createobject("adodb.Connection")
conexion.open(basededatos)
'Se declara la selección de campos de la base de datos
giro = "SELECT Id, Descripcion FROM Giros_Comerciales ORDER BY Descripcion"
set giros = conexion.execute(giro)
%>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Combos dinámicos con AJAX</title>
<script>
//Función para crear un objeto XMLHttpRequest
function crearAjax() {
var Ajax
if (window.XMLHttpRequest) { // Intento de crear el objeto para Mozilla, Safari,...
Ajax = new XMLHttpRequest();
if (Ajax.overrideMimeType) {
//Se establece el tipo de contenido para el objeto
//http_request.overrideMimeType('text/xml');
http_request.overrideMimeType('text/html');
}
} else if (window.ActiveXObject) { // IE
try { //Primero se prueba con la mas reciente versión para IE
Ajax = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try { //Si el explorer no esta actualizado se prueba con la versión anterior
Ajax = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!Ajax) {
alert('¡Por favor, actualice su navegador!');
return false;
}
else
{
return Ajax;
}
}
//Función para actualizar el combo para las empresas
function ActualizarEmpresas (pagina, cmbDelimitador, divContenedora)
{
//Se obtiene la referencia del div
//donde se mostrarán los resultados
var contenedor = document.getElementById(divContenedora);
//Se obtiene el valor seleccionado en el combo delimitador
var valdelimitador = document.getElementById(cmbDelimitador)
var x = valdelimitador.value
//Se contruye la url pasando, como parámetro, el valor seleccionado
var url_final = pagina+'?Id='+x
//Se muestra una imagen de espera en la capa contenedora del combo delimitado
contenedor.innerHTML = '<img src="imagenes/cargando.gif" />'
//Se crea un objeto XMLHttpRequest
var objAjax = crearAjax()
objAjax.open("GET", url_final)
objAjax.onreadystatechange = function() {
if (objAjax.readyState == 4) {
//Se escribe el resultado en la capa contenedora
contenedor.innerHTML = objAjax.responseText;
}
}
objAjax.send(null);
}
</script>
</head>
<body>
<!--Se crea el formulario para mostrar los combos-->
<form name="frmCombos" action="combos.asp" method="post">
<label>Giro comercial</label>
<select name="giros_comerciales" id="giros_comerciales" onchange="ActualizarEmpresas('obten_empresas.asp', 'giros_comerciales', 'Empresas_Relacionadas')">
<option value=""></option>
<%
'Se muestran todos los giros comerciales obtenidos con la consulta
do while not giros.eof
%>
<option value="<%=giros("id")%>"><%=giros("descripcion")%></option>
<%
'Se avanza al siguiente registro
giros.movenext
loop
'Se libera memoria
set giros = nothing
%>
</select>
<p>
<div id="Empresas_Relacionadas">
<label>Empresas</label>
<select name="empresas" id="empresas">
</select>
</div>
</p>
</form>
</body>
</html>
<%
'Se cierra la conexión y se libera memoria
conexion.close()
set conexion = nothing
%>
Por último, sólo tenemos que crear la página "obten_empresas.asp", la cuál es la encargada de obtener las empresas que correspondan al giro comercial seleccionado, para esta página utilizaremos el método HTMLEncode() del objeto server, esto para que caracteres acentuados o símbolos especiales se vean correctamente. Puedes hacer la prueba, primero utilizando el método HTMLEncode() y luego quitarlo para que puedas ver mejor la diferencia. El código es el siguiente:
(obten_empresas.asp)
<%
giro_comercial_id = request.QueryString("id")
'Línea para indicar el driver a ocupar
'para la conexión a la base de datos
basededatos="Driver={SQL Server};"& _
"Server=LOCALHOST;"& _
"Database=AJAX;"& _
"Uid=sa;"& _
"Pwd=;"
'Objeto para realizar la conexión a la base de datos
set conexion = server.createobject("adodb.Connection")
conexion.open(basededatos)
'Se declara la selección de campos de la base de datos
empresa = "SELECT Id, Nombre "& _
"FROM Empresas "& _
"WHERE Giro_Comercial_Id = "&giro_comercial_id&" "& _
"ORDER BY Nombre"
set empresas = conexion.execute(empresa)
%>
<label>Empresas</label>
<select name="empresas" id="empresas">
<%
'Se muestran todas las empresas obtenidas con la consulta
do while not empresas.eof
%>
<option value="<%=empresas("id")%>"><%=Server.HTMLEncode(empresas("nombre"))%></option>
<%
'Se avanza al siguiente registro
empresas.movenext
loop
set empresas = nothing
%>
</select>
Para hacer la prueba sin utilizar el método HTMLEncode sólo hay que modificar este pedazo de código:
<%=Server.HTMLEncode(empresas("nombre"))%>y dejarlo de la siguiente forma:
<%=empresas("nombre")%>Listo, ahora sólo resta probar nuestro código.
***El código fuente de este artículo, la imagen a la que hago referencia en el código y el script para generar la base de datos (La base de datos esta en SQLServer 2000) se pueden descargar desde:
Base de datos Páginas e imágen