Combo dependiente con JSP + Ajax


Introducción

Este es sin duda el tema más recurrente en la programación web: Cómo usar combo dependientes. Es decir, que el contenido de un combo dependa de la selección de otro. Es muy utilizado en los clásicos departamento-provincia-distrito. Además, la manera común es colocar en el atributo onChange del select “maestro” la función “submit()”. Funciona pero no es eficiente.

La solución – ahora – es AJAX. Este pequeño tutorial explica cómo hacer un combo dependiente en AJAX, usando JQuery.

¿Es necesario el JQuery? Puede ser cualquier framework que permita hacer AJAX, pero elijo este porque su instalación y configuración es mínima, quizás nula.

Ingredientes

El proyecto se hará usando:

IDE

NetBeans (el que utilicé en este ejemplo es la versión 6.5.1)

Base de datos

Sample (que viene en el Java DB)

Biblioteca adicional

Spring Framework (para hacer el DAO)

Contenedor de aplicaciones

Glassfish v2



Configuración del proyecto

JQuery


Para agregar la biblioteca de JavaScript JQuery en NetBeans, bastará con entrar a la ventana de propiedades del proyecto (Clic derecho sobre el ícono del proyecto) y en la categoría 'JavaScript Libraries' agregarlo con el botón 'Add...'

Eso incluirá el archivo .js al proyecto. Pero si se desea tener siempre la última versión de esta biblioteca en nuestras aplicaciones, se deberá omitir este paso, y agregar en las páginas que usaremos el JavaScript así:

<script src="http://code.jquery.com/jquery-latest.js"></script>

Spring Framework

Esta configuración solo es para hacer el DAO en nuestra aplicación

La aplicación

El formulario

Necesitamos nuestro formulario que tendrá los combos. Este será el siguiente:

        <form>
<label for="productCode">Product code</label>
<select id="productCode" name="product" onchange="showProducts()">
</select><br/>
<label for="product">Product</label>
<select id="product" name="product"></select>
</form>

Note en cuenta los “id” de cada elemento. Estos son importantes para poder identificar cada objeto del formulario


Como se ve, ningún select tiene valores.

Primero, cargaremos los valores del primer combo. Esto se hace desde javascript en la misma página.

La carga de datos

Este cargará los valores del primer combo

            $(document).ready(function(){
$("#productCode").load("ProductCodeServlet");
})

Esto hace lo siguiente: Cuando el objeto “document” (el documento del HTML) esté listo, llamará a la función que está inscrita.

Esta función hace lo siguiente: al objeto llamado “productCode” cargará los valores que están en el URL “ProductCodeServlet”. Este “ProductCodeServlet” es un servlet que habremos creado. Su método de atención es simple:

protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ProductCodeDao dao = DaoFactory.getInstance().getProductCodeDao();
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<option value=''>Seleccione producto</option>");
List<ProductCode> list = dao.getProductCodes();
try {
for (ProductCode productCode : list) {
out.printf("<option value='%1s'>%2s</option>", productCode.getProdCode(), productCode.getDescription());
}
} finally {
out.close();
}
}

Solo muestra los valores option que se mostrará en el combo de códigos. Estos datos se insertarán como por “arte de magia” en el combo “productCode”.


Ahora, cuando se seleccione un elemento del combo “productCode”, vemos que su atributo “onchange” está llamando a la función “showProducts()”. Ahora, veremos cómo es este método:


            function showProducts(){
//obtiene los objetos productCode,
var code=$("#productCode").val(); //.. y se obtiene el valor
//llama al servlet con el parametro seleccionado
$("#product").load("ProductServlet", {productCode:code})
}

Notar que ahora, la función load() para el objeto product, está recibiendo un argumento

{productCode:code}

Eso es, que va a llamar al servlet ProductServlet y enviará el parámetro “productCode” con el valor contenido en “code”.

Ahora, el servlet de ProductServlet, es el siguiente:


    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String productCode = request.getParameter("productCode");
ProductDao dao = DaoFactory.getInstance().getProductDao();
List<Product> list = dao.getProductsByCode(productCode);
try {
for (Product product : list) {
out.printf("<option value='%1s'>%2s</option>", product.getProductId(), product.getDescription());
}
} finally {
out.close();
}
}

Recursos

El proyecto completo para este tutorial se encuentra aquí

http://diesil-java.googlecode.com/files/MultiComboAjaxJspJQuery-01.tar.gz

Además, si se desea saber algo más de cómo usar el SpringFramework para DAO, revisar este artículo que también escribí:

Dao + Spring

Comments