TUTORIAL DE COMBOS DEPENDIENTES CON AJAX Y JSP Este tutorial es una recopilación de toda la información que pude conseguir respecto a este tema la cual luego de estudiarla la adapte a los requerimiento de mi proyecto, en especial lo referente a ajax que fue algo que desconocía por completo y que me pareció muy interesante aprender, es la primera vez que hago un tutorial , así que intentare hacerlo lo mas entendible que pueda. PASO1: Debemos crear en SQL dos procedimientos Almacenados, bueno esto va variar según los
requerimientos de nuestro sistema, en el caso de estar trabajando con con departamento –provincia
–distrito, tendría que crear tres procedimientos almacenados, donde la lógica y proceso es muy similar, en mi proyecto también implemente combos de departamentos y provincias, pero en este tutorial me limitare hacer el ejemplo de CATEGORIAS Y SUBCATEGORIAS ya que el proceso es muy similar para el otro caso: SP_DEVUELVE CATEGORIA
CREATE PROCEDURE PROCEDURE DEVUELVE CATEGORIA CATEGORIA AS Select* from Categoria (Donde mi tabla categoría tiene dos campos que son idcategoria ,y la descripción de la categoria) SP_DEVUELVE SUBCAT
Aquí si debo entregarle como parámetro de e ntrada al SP, el id_categoria ,y en base a ello me devuelva los campos (id_subcat ,desc_subcat) de mi tabla SUBC ATEGORIAS. El SP, seria de esta forma: CREATE PROCEDURE DEVUELVESUBCAT @idcategoria char(5) AS Select id_subcat,desc_subcat from SUBCATEGORIA where id_categoria =@idcategoria PASO2: En este paso explicare las clases correspondiente que debemos crear en cada CA PA del
proyecto ,en mi caso he trabajado con TRES CAPAS : PAQUETE BEANS: Vamos a crear dos beans categoría y subcategoria BEANS CATEGORIAS: package BEANS; /** *
*/ public class categoria { private String idcategoria; private String descripcion; public categoria() { } public String getIdcategoria() { return idcategoria; } public void setIdcategoria(String idcategoria) { this.idcategoria = idcategoria; } public categoria(String descripcion) { this.descripcion = descripcion; } public String getDescripcion() { return descripcion; } public void setDescripcion(String descripcion) { this.descripcion = descripcion; }
}
BEANS SUBCATEGORIA package BEANS; /** * */ public class subcategoria { private String idsubcat; private String idcategoria; private String descrip; public subcategoria() { } public String getDescrip() { return descrip; } public void setDescrip(String descrip) { this.descrip = descrip; } public String getIdcategoria() {
return idcategoria; } public void setIdcategoria(String idcategoria) { this.idcategoria = idcategoria; } public String getIdsubcat() { return idsubcat; } public void setIdsubcat(String idsubcat) { this.idsubcat = idsubcat; }
}
PAQUETE DAO: dentro del paquete DAO ,se ha cre ado una clase llamada búsquedas ,la cual
contiene los siguientes métodos que interactúan con la base de datos y que invocaran a los procedimientos almacenados creados previamente. public Vector buscadorCategorias() {
Vector V=new Vector(); try { conexion con = new conexion(); cn = con.getConexion(); CallableStatement Cstmt; Cstmt = cn.prepareCall("{call DEVUELVECATEGORIA}"); ResultSet rs; rs=Cstmt.executeQuery(); while(rs.next()){ categoria cat =new categoria(); cat.setIdcategoria(rs.getString(1)); cat.setDescripcion(rs.getString(2)); V.addElement(cat); } } catch (SQLException e) { System.out.println("error al devolver categoria"); } finally { return V; } }
public Vector buscadorSubcategorias(String Idcategoria) { Vector B=new Vector(); try { conexion con = new conexion(); cn = con.getConexion(); CallableStatement Cstmt; Cstmt = cn.prepareCall("{call DEVUELVESUBCAT(?)}"); Cstmt.setString(1, Idcategoria); ResultSet rs; rs=Cstmt.executeQuery(); while(rs.next()){ subcategoria subcat =new subcategoria(); subcat.setIdsubcat(rs.getString(1)); subcat.setDescrip(rs.getString(2)); B.addElement(subcat); } } catch (SQLException e) { System.out.println("error al devolver subcategoria"); } finally { return B; } }
PAQUETE UTILITARIOS: En este paquete se ha creado una clase llamada llenarcombos,la cual
invocara los métodos creados en la clases búsquedas del paquete DAO public Vector comboCategorias(){ busquedas B=new busquedas(); return B.buscadorCategorias(); }
public Vector comboSubCategorias(String Idcategoria){ busquedas B=new busquedas(); return B.buscadorSubcategorias(Idcategoria); }
PASO3:
Ahora trabajaremos dentro de la pagina JSP, en mi proyecto la encontrara con el nombre de new_producto, para ello primero debemos importar los paquetes y clases java que vamos a
utilizar dentro de nuestra pagina ,para ellos nos ubicaremos dentro de la etiqueta Page que se encuentra al inicio de la pagina JSP: <%@page contentType="text/html" pageEncoding="UTF-8" import="DAO.busquedas,utilitarios.llenarcombos,java.util.Vector,BEANS.categoria,BEANS.subca tegoria"%>
PASO 4:
Una vez importadas nuestros paquetes y clases Java , dentro del formulario ,nos ubicamos dentro de las etiquetas SELECT del combo categorías e invocaremos a los métodos creados dentro de la clase llenarcombos (ComboCategorias) ,para luego obtener los elementos dela base de datos uno a uno mediante un bucle y almacenarlos dentro de un vector.
Deben tener en cuenta que en la línea de código en donde muestro la descripción categoría en la opción valué del combo se esta poniendo el id de la categoría, esto para que cuando mandemos la categoría se tome el id para poder realizar la búsqueda en la tabla subcategorias.
PASO 5: Ahora veremos la parte de AJAX, para esto tenemos un archivo javascript ajax_subcategoria.js en el cual tendremos el siguiente código:
Veamos lo que hace este código: Var xmlHttp: En esta línea lo que se hace es declarar una variable de tipo java script de nombre
xmlHttp (se puede haber usado cualquier otro nombre) ,en esta variable vamos almacenar el objeto (XMLHttpRequest ) .Este objeto es muy importante, ya que en este se basa el funcionamiento del Ajax . Creamos la Funcion getsubcat ,a la cual le estamos enviando como parámetro el idcategoria luego en la parte mas abajo vemos que hacemos la referencia a la pagina ajax_subcategoria.jsp, que es en la que recuperaremos la información de la tabla de subcategorias enviando como parámetro el idcategoria.
Para realizar la petición al servidor vamos a instanciar el objeto (XMLHttpRequest) dentro de la variable xmlHttp. Lo que hace el objeto XMLHttpRequest , es preparar la función de
respuesta, realiza la petición al servidor y ejecuta la función de respuesta. Todas las aplicaciones realizadas con técnicas de AJAX deben instanciar en primer lugar el objeto XMLHttpRequest , que es el objeto clave que permite realizar comunicaciones con el servidor en segundo plano, sin necesidad de recargar las páginas.
La implementación del objeto XMLHttpRequest depende de cada navegador, por lo que es necesario emplear una discriminación sencilla en función del navegador en el que se está ejecutando el código: if(window.XMLHttpRequest) { // Navegadore s que siguen l os estándares peticion_http = new XMLHttpRequest(); } else if(window.ActiveXObject) { // Navegadore s obsoletos peticion_http = new ActiveXObject("Microsoft.XMLHTTP"); }
Yo encontré dos variantes de este objeto y las dos me funcionaron ,así que no tuve problemas ,esta son: new ActiveXObject("Msxml2.XMLHTTP"); new ActiveXObject("Microsoft.XMLHTTP");
Los navegadores que siguen los estándares (Firefox, Safari, Opera, Internet Explorer 7 y 8) implementan el objeto XMLHttpRequest de forma nativa, por lo que se puede obtener a través del objeto window . Los navegadores obsoletos (Internet Explorer 6 y anteriores) implementan el objeto XMLHttpRequest como un objeto de tipo ActiveX. Ahora continuare explicando las demás líneas de código: var url="ajax_subcategoria.jsp"; (pagina de la cual recuperaremos la información de la tabla subcategorias) url=url +"?idcategoria="+idcategoria; ( adjunto a la pagina ajax_subcategoria el idcategoria ,para que busque las subcategorias según el idcategoria que se le envie) xmlHttp.onreadystatechange=resultado_subcategoria; onreadystatechange es una propiedad del objeto XMLHttpRequest la cual almacena el nombre
de la función que se ejecutará cuando el objeto XMLHttpRequest cambie de estado,es decir cuando reciba la respuesta del sevidor,se ejecutara la función resultado_subcategoria
xmlHttp.open("GET",url,true); xmlHttp.send(null); Las instrucciones anteriores realizan el tipo de petición que se va enviar al servidor, se trata de una petición de tipo GET simple que no envía ningún parámetro al servidor. La petición HTTP se crea mediante el método open() , en el que se incluye el tipo de petición (GET), la URL solicitada (ajax_subcategoria.jsp + idcategoria) y un tercer parámetro que vale true . Una vez creada la petición HTTP, se envía al servidor mediante el método
send() .
function resultado_subcategoria(){ if(xmlHttp.readyState==4){ document.getElementById("result_subcategoria").innerHTML= xmlHttp.responseText;
} La función resultado_subcategoria() se ejecutara cuando se reciba la respuesta del servidor La primera línea if(xmlHttp.readyState==4) comprueba en primer lugar que se ha recibido la respuesta del servidor (mediante el valor de la propiedad readyState ). La propiedad readyState Almacena el estado del requerimiento hecho al servidor, su valores pueden ser de 5 tipos:
0 No inicializado (el método open no a sido llamado)
1 Cargando (se llamó al método open)
2 Cargado (se llamó al método send y ya tenemos la cabecera de la petición HTTP y el status)
3 Interactivo (la propiedad responseText tiene datos parciales)
4 Completado (la propiedad responseText tiene todos los datos pedidos al servidor)
Una vez comprobado si se ha recibido alguna respuesta, simplemente se muestra por pantalla el contenido de la respuesta del servidor (en este caso, el contenido del archivo solicitado) mediante la propiedad responseText . document.getElementById("result_subcategoria").innerHTML= xmlHttp.responseText;
document.getElementbyid(esta propiedad de java script nos permite identificar un determinado objeto dentro de una pagina por su id ,es decir identifica al objeto que tenga el id=result_subcategoria ,y cambia su contenido por la respuesta enviada desde el servidor que en mi caso van a ser todas las subcategorias relacionadas al idcategoria enviado como parametro, podemos cambiar el contenido mediante la propiedad InnerHTML ,esta propiedad nos permite entre otras cosas dar efectos dinámicos a nuestra pagina.,) Entonces el objeto de mi pagina cuyo id=("result_subcategoria"). Es donde se me mostraran los resultados obtenidos . Esto lo veremos en el siguiente paso.
PASO 6: Ahora vamos a crear una nueva pagina JSP , la encontrara con el nombre ajax_subcategorias.jsp ,cuyo código es el siguiente:
En este código, como en el caso anterior primero importaremos dentro de la etiqueta page los paquetes y clases que usaremos. Luego declaramos e inicializamos las variables de mi tabla subcategorias que son de tipo string. Creamos un objeto vector B; Instanciamos el BEANS subcategorias como subcat. Obtenemos el parámetro idcategoria enviado desde la pagina JSP new_producto () Luego en la siguiente línea de código invocamos al método ComboSubcategorias de la clase llenar combos, verificamos que el vector no este vacio y mostramos dichos elementos en el combos subcategorias.
IMPORTANTE: para poder enviar a esta pagina (ajax_subcategorias.jsp ) el parámetro idcategoria enviado desde la pagina new_producto() no debemos olvidar importar la librería “ajax_categoria.js” dentro de las etiquetas HEAD de la pagina new_producto () <script type="text/javascript" src="script_js/ajax_categoria.js">
Ahora dentro de nuestra pagina new_producto ,nos ubicaremos dentro de las etiquetas select del combo categorías y en el evento onchange ,invocaremos a la función getsubcat(this.value), la cual fue vista anteriormente ,esta función va recibir como parámetro el idcategoria ,almacenado en la propiedad value del combo categoría y la va enviar al servidor para que la procese y envié la respuesta ,la cual se mostrara en el combo subcategorias .
Ahora para mostrar el resultado ,observar en el código de abajo que estoy asignando a la etiqueda div que contiene al combo subcategorias el id=result_subcategoria que es donde quiero que se me filtren los resultados.
Bueno eso es todo con respecto a los combos dependientes .espero haberme dejado entender y que le sea mucha utilidad a usted y a las personas que lo lean.
PAGINACION CON JSP Y ARRAYLIST: En mi proyecto podrá encontrar dos tipos de paginación una realizado con resultset que utilize para mi intranet y la otra con arraylist que utilice para la mi catalogo . En el primer tipo de paginación el proceso se realiza dentro de la misma pagina JSP ,la encontrara con los nombre de listas ; listar_productos,listar_clientes,etc En la de tipo Arraylist , he creado una clase dentro del paquete DAO llamado Opera ,en el cual obtengo desde mi base de datos los registro de los productos ,y luego lo almaceno en un objeto de tipo arraylist ,este objeto luego lo tengo que invocar en mi pagina JSP ,que se llama index5.jsp,donde importo el paquete y la clase DAO.opera, y llamo al objeto de tipo arraylist. Puede ver el código en mi pagina index5.jsp.