martes, 12 de mayo de 2009

Combo dependiente con JSP + Ajax

Este es sin duda el tema más buscado para los que desarrollan formularios web:

Combos dependientes en JSP usando AJAX

Esto es clásico en los ejemplos de combos tipo departamento-provincia-distrito, cuando los elementos de un combo depende de la selección de otro.

Pues ya, aquí está...
... y totalmente actualizado!!

Aquí lo explicamos con JQuery y AngularJS, y de regalo.. con Bootstrap y Material Design


Esta aplicación tiene tres partes.
  1. Capa de datos
  2. Servicios "ajax"
  3. Vista.

Capa de datos

La primera es la capa de datos, la cual está implementada por un DAO. Aquí he implementado con:
  • Spring. Para instanciar los DAO
  • Base de datos Apache Derby. Use la base de datos ejemplo "sample" que viene en el JDK. Pueden usar cualquier, pero yo usé este porque ya está implementado.
  • DBCP para manejar el pool de conexiones
  • Clase singleton justamente para tener un solo factory que me obtenga la conexión a la base de datos.
Las dependencias en pom.xml para esta parte están dadas aquí

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-dbcp2</artifactId>
            <version>2.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.derby</groupId>
            <artifactId>derbyclient</artifactId>
            <version>10.12.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.2.5.RELEASE</version>
        </dependency>

El archivo spring.xml que crea la conexión a la base de datos es este:


La implementación del DAO para obtener el listado de ProductCode es este:
Y listo, lo tenemos totalmente aislado para lo que queramos.

Servicios Ajax

Está mal dicho el nombre, pero consiste en un servlet que devuelve los datos para ser consumidos como Ajax en nuestro HTML. Como son dos tablas, he creado dos servlets. Aquí está uno, el que corresponde a ProductCode.. el otro es similar.


Consiste simplemente en usar el DAO, luego convertir el resultado en JSON (que ya es estándar) para devolvérselo al cliente

Capa de presentación (Vista)

Esta es la parte interesante del proyecto.

JQuery

Con JQuery consiste en:

  1. obtener la lista del servlet (línea 49)
  2. Recorrer la lista (línea 52)
  3. Por cada elemento crear un elemento option...(Línea 53)
  4. .. colocándole las propiedades como el valor (Línea 54)
  5. ... el texto a mostrar (Línea 55)
  6. .. y colocándolo al combo (Línea 56)
  7. De paso, capturamos el evento "on change" del combo (línea 58) para que ejecute el método respectivo (línea 61)
  8. Este método consiste en tomar el valor del combo que cambió (línea 62)
  9. .. llama al servlet para obtener la lista (línea 65)
  10. .. con el parámetro respectivo (línea 66)
  11. y construimos las opciones del combo. Naturalmente hay que limpiarlo (línea 69) y agregar las líneas opciones como se hizo con el otro combo.

Y este es el resultado:

AngularJS


Este es el mismo ejemplo, pero usando AngularJS. Notemos que no fue necesario crear todo un servidor RESTful, ya que nuestro servlet devuelve los valores como si fuera un servidor JAX-RS. Claro, no es exactamente igual, pero como usa el estándar JSON, será más fácil hacer la portabilidad.
  1. Los select (línea 32 y 38) tienen enlazados por el modelo y el controlador los valores a cargar. Los modelos son llenados en el script que está a partir de la línea 46
  2. Nuevamente obtiene los valores del servlet (Línea 49 y 51) 
  3. Cuando es obtenida la lista, se le pasa a la variable de alcance productCodeList (línea 53) En ese momento, las opciones del combo son actualizadas (línea 33)
  4. Cuando el valor del combo productCode cambia, ejecuta el método productCodeOnChange() que fue definido en la directiva ng-change.
  5. El método&nbsp productCodeOnChange() funciona de la misma manera que el otro combo:
  6. .. obtiene la lista del servlet (línea 56 y 58)
  7. .. usando el parámetro el parámetro respectivo (línea 60)
  8. Y cuando se tienen los valores, son pasados a la variable productList (línea 63) que actualiza inmediatamente el combo (Línea 36)

Y este es el resultado. No tiene mucha diferencia visual, pero el código fue mucho más reducido, ya que no hemos tenido que pelearnos con el DOM

JQuery + Bootstrap

Bootstrap es un conjunto de estilos que ayudan a mejorar visualmente la aplicación sin hacer mucho código. Al código anterior en JQuery le pondremos algunas directivas de Bootstrap, y luce así


El código fuente de está página está acá:

angularjs + Material Design

Material Design son especificaciones web elaborado por Google para que las aplicaciones luzcan como... si fueran de Google. Además, la gente de AngularJS hizo una extensión de Angular para Material Design, llamada Angular Material. Consiste en usar las mismas instrucciones Angular, pero con el módulo "ngMaterial"... y cambiar algunos tags para que luzcan como Google. 

Así luce la aplicación usando Angular Material.

El código fuente de esta página está acá:

Código fuente del proyecto

No me puedo terminar este post si no comparto el código fuente de este ejemplo.