Esto es para compartir, para que no le pase a nadie lo que me ha pasado a mi (de buscar y no encontrar).
El framework que utilizo es Struts (que si, que ya tenemos Spring, pero bueno, me corre prisa).
Me he basado en este ejemplo (hecho con PHP)
http://www.hellogoogle.com/selector_combo_ajax_provincias_localidades/
Básicamente necesitamos, el fichero XML para cargar, en mi caso provincias y localidades (Podemos utilizar el fichero XML del autor, así como la librería js)
En primer lugar necesitamos una jsp donde cargar los combos, con el siguiente código.
Nota: tengo que mejorar cosas de código, como la de obtener el XML
/****************************/
datosProvinciasELocalidades.jsp
Código:
<script language="JavaScript" src='<html:rewrite module="" page="/js/comun/ajaxcode.js"/>'></script>
<script>
/* localización del xml */
url="http://localhost:8080/sti/js/xml/provinciaselocalidades.xml";
var options = '';
var index = 0;
$.get(url, function(xml){
$("provincia",xml).each(function(i){
index = i+1;
options += '<option value="' + this.getAttribute('id') + '">' + this.childNodes[1].textContent + '</option>';
})
$("select#provinciaList").html(options);
})
</script>
<%-- maquetalo ao voso gusto --%>
<select name="provinciaList" id="provinciaList" onChange="return provinciaListOnChange()">
<option >--Escolla unha provincia--</option>
</select>
<select name="localidadList" id="localidadList">
<option >--Seleccione unha localidade--</option>
</select>
<span id="advice"></span>
</span>
La funcion provinciaListOnChange() la he modificado del original para que recuperase las provincias a través de un servlet, queda así el código reescrito:
dentro de
ajaxcode.js
Nota: si, si, ya se que tengo que cambiarle las URLs absolutas :D
Código:
function provinciaListOnChange() {
var to=document.getElementById("advice");
to.innerHTML="<img src='http://localhost:8080/sti/imaxes/loading.gif' align='absmiddle'>";
var provinciaList = document.getElementById("provinciaList");
var selectedprovincia = provinciaList.options[provinciaList.selectedIndex].value;
var requestUrl;
requestUrl = "http://localhost:8080/sti/servlet/XMLDataProvider" + "?filter=" + encodeURIComponent(selectedprovincia);
CreateXmlHttpObj();
if(XmlHttpObj)
{
XmlHttpObj.onreadystatechange = StateChangeHandler;
XmlHttpObj.open( "POST", requestUrl, true );
XmlHttpObj.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
XmlHttpObj.send('');
}
}
Por cierto, hay que darlo de alta en el web.xml de la aplicación
Finalmente el código del Servlet
Código:
package package es.<empaquetado>.presentacion.servlets;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import es.<empaquetado>.util.Utilidades;
public class XMLDataProvider extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
//set the content type
response.setContentType("text/xml");
response.setHeader("Cache-Control", "no-cache");
//get the PrintWriter object to write the html page
PrintWriter writer = response.getWriter();
String filter = request.getParameter("filter");
Utilidades.getLogger().debug("filter: " + filter);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
/* no se si el la ubicación más correcta :D */
Document document = builder.parse(new File("/var/opt/jboss/sti/provinciaselocalidades.xml"));
XPath xpath = XPathFactory.newInstance().newXPath();
String expression = "/lista/provincia[@id="+ filter + "]/localidades";
NodeList nodes = (NodeList) xpath.evaluate(expression, document.getDocumentElement(), XPathConstants.NODESET);
writer.println(Utilidades.Nodes2String(nodes));
writer.close();
} catch (SAXParseException spe) {
Utilidades.getLogger().error("error: " + spe);
} catch (SAXException sxe) {
Utilidades.getLogger().error("error: " + sxe);
} catch (ParserConfigurationException pce) {
// Parser with specified options can't be built
Utilidades.getLogger().error("error: " + pce);
} catch (IOException ioe) {
Utilidades.getLogger().error("error: " + ioe);
} catch (Exception e) {
System.out.println("error: " + e);
}
}
}
Bueno, ya teneis todos los elementos necesarios, espero que os sirva de ayuda...
No seais muy críticos :D