lunedì 25 agosto 2008

Select con Struts e Ajax

Come al solito non avendo nulla da fare nei fine settimana faccio quello che faccio tutti i giorni "tentare di conquistgare il mondo"... no scherzo cerco di imparare cose  nuove sulla programmazione...

Questa volta però ho coniugato il piacere al dovere.... In pratica dato che nel progetto in cui lavoro presso l'azienda che presto consulenza devo popolare delle select dinamicamente (il classico gioco che alla selezione di un opzione di una select l'altra si deve popolare dinamicamente in base alla scelta) mi sono chiesto come risolvere la cosa... Ovviamente javascript soltanto è troppo poco se no non starei a pensarci... Tagliando corto il problema l'ho risolto utizzando Ajax.



Da premettere che ero solo a conoscenza di quest'ultimo e sapevo solo le possibilità che offriva, ma nn l'ho mai usato però sapevo che faceva al caso mio quindi mi son messo sotto e ho approfondito la cosa.

Dato il buon risultato che ho ottenuto nel mio test ho deciso di pubblicare questo tutorial così qualcuno si evita un pomeriggio di prove se avesse bisogno come me di tale funzione.

Bene prima di addentrarci nel codice voglio far capire perchè ho scelto ajax e non semplice javascript. I dati che devono popolare le select sono diverse migliaia e sono immagazinati sul db dato che tirarli su tutti dal db per poi prepararmeli per la  select non è cosa buona oltre ad uno spreco di risorse e rallentamento dell'applicazione mi serviva quind qualcosa che senza ricaricare pagina mi venivano forniti solo i dati necessari dal db. Sapendo che ajax permetteva di fare richieste asincrone ho deciso di testare la cosa.

Ovviamente essendo fine settimana non potevo testarla direttamente sul progetto sul quale cosi ho deciso di farmene uno di prova per lo scopo.

Ci siamo quasi fra poco comincio con il tutorial, prima però voglio precisare che come sempre do per scontato che chi legge abbia delle nozioni di base... in questo caso di struts, javascript e j2ee in generale.

Il fulcro del test è dato dagli script ajax e da una action struts. Spiego meglio cosa si ha intenzione di fare. Al cambiamento del contenuto delle select Regione verrà richiamata una una funzione javascript che prepara la richiesta http e la passa alla funzione ajax che effettua la chiamata alla action incaricata. La action rrecupera i valori dal datasource per la select Provincia che dovrà essere popolata in base alla regione selezionata. I dati saranno messi dalla action nel response sottoforma di xml. Ajax al momento della ricezione del resonse richiamerà un funzione javascript, che tramite DOM (fate un giro su google), parsa l'xml ottenuto e, ricavati i dati richiesti, popola la select delle province. Seguendo il tutorial vi sarà più chiaro.

Ecco che si comincia, illustrerò in base ai passi che ho seguito io. Per prima cosa preparatevi la classica struttura di un progetto basato su struts (non farò riferimento a nomi di package e altro resterò molto generale) nel mio caso me la sono fatta preparare da netbeans.

Fatto ciò prepariamo il model.. ho creato prima l'unico FormBean che mi serve sia come formBean per recuperare le informazioni dalla request sia come dato da trattare con le  classiche operazioni di salvataggio e presentazione in lista, chiamato LocalitaActionForm ecco il codice:

LocalitaActionForm.java

package piergiuseppe82.ajaxselect.struts.form;

import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;


public class LocalitaActionForm extends org.apache.struts.action.ActionForm {

private String regione;
private String provincia;
private String citta;
private String cap;


/**
*
*/
public LocalitaActionForm() {
super();
// TODO Auto-generated constructor stub
}


public String getRegione() {
return regione;
}


public void setRegione(String regione) {
this.regione = regione;
}


public String getProvincia() {
return provincia;
}


public void setProvincia(String provincia) {
this.provincia = provincia;
}


public String getCitta() {
return citta;
}


public void setCitta(String citta) {
this.citta = citta;
}


public String getCap() {
return cap;
}


public void setCap(String cap) {
this.cap = cap;
}
}


Come vedete il mio dato rappresenta un luogo che ha come attributi Regione, Provincia, Citta e Cap e relativi metodi accessori. Il mio scopo quindi è quello di popolare quattro select rispettive agli attributi del form bean per applicare dei filtri ad una collezione di quest'ultimo. L'effetto che devo avere, ripeto, è quello di popolare, ad esempio, la select delle Province in base al valore scelto nella select delle Regioni e così via per città e cap senza ricaricare la pagina.

Preparato il dato da trattare creiamo la nostra classe factory che ci fa anche da datasource e da bean da passare alla jsp (ripeto che devo solo testare una select non creare un applicazione da vendere quindi perdonatemi ciò) e che mi tengo in sessione ecco il codice:

Dati.java

package piergiuseppe82.ajaxselect.data;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import piergiuseppe82.ajaxselect.struts.form.LocalitaActionForm;





public class Dati {

List<LocalitaActionForm> localitalist;
List<LocalitaActionForm> ret;
private boolean filtro;
public Dati() {
this.localitalist = new ArrayList();
}


public void addLocalita(LocalitaActionForm localita){
this.localitalist.add(localita);
}


public List getAllLocalita(){
return this.localitalist;
}


public List getRegioni(){
List tmp = new ArrayList();
Iterator i = this.localitalist.iterator();
while(i.hasNext()){
LocalitaActionForm loc = (LocalitaActionForm)i.next();
if(tmp.indexOf(loc.getRegione())==-1){
tmp.add(loc.getRegione());
}


}
return tmp;
}


public List getProvince(String regione) {

List tmp = new ArrayList();
Iterator i = this.localitalist.iterator();
while (i.hasNext()) {
LocalitaActionForm loc = (LocalitaActionForm) i.next();
if (loc.getRegione().equals(regione) && tmp.indexOf(loc.getProvincia())==-1) {
tmp.add(loc.getProvincia());
}
}
return tmp;


}

public List getCitta(String provincia) {

List tmp = new ArrayList();
Iterator i = this.localitalist.iterator();
while (i.hasNext()) {
LocalitaActionForm loc = (LocalitaActionForm) i.next();
if (loc.getProvincia().equals(provincia) && tmp.indexOf(loc.getCitta())==-1) {
tmp.add(loc.getCitta());
}
}
return tmp;


}

public List getCap(String citta) {

List tmp = new ArrayList();
Iterator i = this.localitalist.iterator();
while (i.hasNext()) {
LocalitaActionForm loc = (LocalitaActionForm) i.next();
if (loc.getCitta().equals(citta) && tmp.indexOf(loc.getCap())==-1) {
tmp.add(loc.getCap());
}
}
return tmp;


}

public void filtraDati(String regione, String provincia, String citta, String cap) {
ret = new ArrayList();
if (!"Regione".equals(regione)) {


Iterator i = this.localitalist.iterator();
while (i.hasNext()) {
LocalitaActionForm loc = (LocalitaActionForm) i.next();
if (loc.getRegione().equals(regione)) {
ret.add(loc);
}
}


if (!"Provincia".equals(provincia)) {
List tmp = new ArrayList();
i = ret.iterator();
while (i.hasNext()) {
LocalitaActionForm loc = (LocalitaActionForm) i.next();
if (loc.getProvincia().equals(provincia)) {
tmp.add(loc);
}
}
ret = tmp;
if (!"Citta".equals(citta)) {
tmp = new ArrayList();
i = ret.iterator();
while (i.hasNext()) {
LocalitaActionForm loc = (LocalitaActionForm) i.next();
if (loc.getCitta().equals(citta)) {
tmp.add(loc);
}
}
ret = tmp;
if (!"Cap".equals(cap)) {
tmp = new ArrayList();
i = ret.iterator();
while (i.hasNext()) {
LocalitaActionForm loc = (LocalitaActionForm) i.next();
if (loc.getCap().equals(cap)) {
tmp.add(loc);
}
}
ret = tmp;
}
}
}


}else{
this.filtro= false;
}


}

public List getDatiFiltrati(){
return this.ret;
}
//Per l'utilita di questi due metodi guardate il codice di FiltraAction e lista.jsp
public boolean getFiltro() {
return filtro;
}


public void setFiltro(boolean filtro) {
this.filtro = filtro;
}


}

Scritta la nostra classe datasource-factory passiamo alle nostre belle action. Nel nostro caso ne abbiamo tre una per il salvataggio di un luogo "SaveAction.java" e passa tutti i contenuti salvati alla lista.jsp . Una che esegue il filtro "FiltraAction.java" sui contenuti e passa solo i contenuti richiesti sempre alla lista.jsp tramite il forward di struts.

SaveAction.java

package piergiuseppe82.ajaxselect.struts.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import javax.servlet.http.HttpSession;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForward;
import piergiuseppe82.ajaxselect.data.Dati;
import piergiuseppe82.ajaxselect.struts.form.LocalitaActionForm;


public class SaveAction extends org.apache.struts.action.Action {

private final static String SUCCESS = "success";

public ActionForward execute(ActionMapping mapping, ActionForm  form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {


LocalitaActionForm locform = (LocalitaActionForm) form;

Dati dati =  getDatiFromSession(request);

dati.addLocalita(locform);
request.setAttribute("dati", dati);
dati.setFiltro(false);
return mapping.findForward(SUCCESS);


}

private Dati getDatiFromSession(HttpServletRequest req) {

HttpSession session = req.getSession(true);
Dati dati = (Dati)session.getAttribute("dati");


if (dati == null) {
dati = new Dati();
session.setAttribute("dati", dati);
}


return dati;
}
}


FiltraAction.java

package piergiuseppe82.ajaxselect.struts.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import javax.servlet.http.HttpSession;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForward;
import piergiuseppe82.ajaxselect.data.Dati;


public class FiltraAction extends org.apache.struts.action.Action {

private final static String SUCCESS = "success";

public ActionForward execute(ActionMapping mapping, ActionForm  form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
Dati dati =  getDatiFromSession(request);
String regione = request.getParameter("reg");
String provincia = request.getParameter("pro");
String citta = request.getParameter("city");
String cap = request.getParameter("cap");
dati.setFiltro(true);
dati.filtraDati(regione, provincia, citta, cap);


request.setAttribute("dati", dati);
return mapping.findForward(SUCCESS);


}
private Dati getDatiFromSession(HttpServletRequest req) {


HttpSession session = req.getSession(true);
Dati dati = (Dati)session.getAttribute("dati");


if (dati == null) {
dati = new Dati();
session.setAttribute("dati", dati);
}


return dati;
}
}


Infine la più importante nel nostro caso quella che ci permette di ottenere i dati dal datatasource per popolare le nostre select. Come detto in precedenza la action seguente recupera i dati dal datasource (nel nostro caso la classe Dati messa in sessione) per il tipo di select. Ottenuti i dati li passa ad un metodo statico di una classe che ho chiamato SelectUtil e li restituisce come documento xml. Quindi scrive nel response l'xml in modo da essere recuperato dallo script ajax. Ecco la classe:

Select.java

package piergiuseppe82.ajaxselect.struts.action;

import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import javax.servlet.http.HttpSession;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForward;
import piergiuseppe82.ajaxselect.data.Dati;
import piergiuseppe82.ajaxselect.data.SelectUtil;


public class Select extends org.apache.struts.action.Action {

private final static String SUCCESS = "success";

public ActionForward execute(ActionMapping mapping, ActionForm  form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {


response.setContentType("text/xml");
Dati dati = getDatiFromSession(request);
String value = request.getParameter("value");
String selectName =request.getParameter("select");
if("reg".equals(selectName)){
List pro = dati.getProvince(value);
response.getWriter().write(SelectUtil.toXml("Provincia", pro));
}
if("pro".equals(selectName)){
List pro = dati.getCitta(value);
response.getWriter().write(SelectUtil.toXml("Citta", pro));
}
if("city".equals(selectName)){
List pro = dati.getCap(value);
response.getWriter().write(SelectUtil.toXml("Cap", pro));
}


return mapping.findForward(SUCCESS);

}

private Dati getDatiFromSession(HttpServletRequest req) {

HttpSession session = req.getSession(true);
Dati dati = (Dati)session.getAttribute("dati");


if (dati == null) {
dati = new Dati();
session.setAttribute("dati", dati);
}


return dati;
}
}


e la classe di utilità che genera l'xml:

SelectUtil.java

package piergiuseppe82.ajaxselect.data;

import java.util.Iterator;
import java.util.List;
public class SelectUtil {


public static String toXml(String name, List province) {

StringBuffer xml = new StringBuffer();
xml.append("<?xml version=\"1.0\"?>\n");
xml.append("<selectoption name=\"" + name + "\">\n");
xml.append("<option>\n");
xml.append("<name>");
xml.append(name);
xml.append("</name>\n");
xml.append("<value>");
xml.append(name);
xml.append("</value>\n");
xml.append("</option>\n");
Iterator<String> i = province.iterator();
while (i.hasNext()) {
String s = i.next();
xml.append("<option>\n");
xml.append("<name>");
xml.append(s);
xml.append("</name>\n");
xml.append("<value>");
xml.append(s);
xml.append("</value>\n");
xml.append("</option>\n");
}
xml.append("</selectoption>\n");
return xml.toString();


}
}


Prima di passare agli script ecco le due jsp una con il solo form per inserire una località e che richiama la action per il salvataggio e l'altra che presenta i dati e richiamata dal forward delle action di salvataggio e filtro:

index.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-nested"  prefix="nested"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">


<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>AjaxSelect</title>
</head>
<body>
<h2>Inserisci Luogo</h2>
<form action="save.do" method="POST">
Regione:<input type="text" name="regione" value="" /><br>
Provincia:<input type="text" name="provincia" value="" /><br>
Citta:<input type="text" name="citta" value="" /><br>
Cap:<input type="text" name="cap" value="" /><br>
<input type="submit" value="Salva" name="save" />
</form>
</body>


</html>

lista.jsp

<%@ taglib uri="http://jakarta.apache.org/struts/tags-bean" prefix="bean" %>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-logic" prefix="logic" %>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-nested"  prefix="nested"%>
<html:html locale="true">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Select Ajax</title>
<script type="text/javascript" language="javascript" src="script/ajax1.js"></script>
<script type="text/javascript" language="javascript" src="script/select.js"></script>


<html:base/>
</head>
<body style="background-color: white">
<nested:root name="dati">
Filtra:<br>
<form name="filtro" action="filtra.do" method="POST">


<select name="reg" onchange="changeSelect('reg');">
<option>Regione</option>
<nested:iterate id="REGID" property="regioni">
<option><nested:write name="REGID"/></option>
</nested:iterate>
</select>
<select name="pro" onchange="changeSelect('pro');">
<option>Provincia</option>
</select>
<select name="city" onchange="changeSelect('city');">
<option>Citta</option>
</select>
<select name="cap">
<option>Cap</option>
</select>
<input type="submit" value="Cerca" name="cerca" />
</form>


<table border="1">
<tr><td> <b>REGIONE</b> </td><td><b>PROVINCIA</b></td><td><b>CITTA</b></td><td><b>CAP</b></td></tr>
<nested:equal property="filtro" value="false">
<nested:iterate property="allLocalita">
<tr><td> <nested:write property="regione"/> </td><td><nested:write property="provincia"/></td>
<td><nested:write property="citta"/></td><td><nested:write property="cap"/></td></tr>
</nested:iterate>
</nested:equal>
<nested:equal property="filtro" value="true">
<nested:iterate property="datiFiltrati">
<tr><td> <nested:write property="regione"/> </td><td><nested:write property="provincia"/></td>
<td><nested:write property="citta"/></td><td><nested:write property="cap"/></td></tr>
</nested:iterate>
</nested:equal>
</table>
</nested:root>
<br><br>
<a href="index.jsp">Torna al form</a>
</body>
</html:html>


per completezza vi do anche lo struts-config in modo da vedere il workflow dell'applicazione:

struts-config.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">
<struts-config>
<form-beans>
<form-bean name="LocalitaActionForm" type="piergiuseppe82.ajaxselect.struts.form.LocalitaActionForm"/>
</form-beans>
<global-exceptions>
</global-exceptions>
<global-forwards>
<forward name="welcome"  path="/Welcome.do"/>
</global-forwards>
<action-mappings>
<action input="/index.jsp" name="LocalitaActionForm" path="/save" scope="request" type="piergiuseppe82.ajaxselect.struts.action.SaveAction" validate="false">
<forward name="success" path="/lista.jsp"/>
</action>
<action path="/filtra" type="piergiuseppe82.ajaxselect.struts.action.FiltraAction">
<forward name="success" path="/lista.jsp"/>
</action>
<action path="/select" type="piergiuseppe82.ajaxselect.struts.action.Select"/>
</action-mappings>
<controller processorClass="org.apache.struts.tiles.TilesRequestProcessor"/>
<message-resources parameter="pieergiuseppe82/ajaxselect/struts/ApplicationResource"/>


<plug-in className="org.apache.struts.tiles.TilesPlugin" >
<set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" />
<set-property property="moduleAware" value="true" />
</plug-in>


<!-- ========================= Validator plugin ================================= -->
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>
</struts-config>


In questo momento potete testare già la generazione dell'xml. Deployate l'applicazione nel vostro application server e richiamatela dal browser. Vi apparirà la pagina di inserimento dei dati inserite qualcosa (io ad esempio ho inserito qualche localuità in calabria... si sono calabrese) e scrivete questo url nel browser: "http://localhost:8080/AjaxSelect/select.do?value=Calabria&select=reg" . Ovviamente se avete inserito localita con regione diversa cambiatela nell'url. Il risultato che ho è l'xml con l'elenco delle province per quella regione. In pratica ho detto alla action select attraverso i parametri passati che ho cambiato la select con nome "reg", quindi mi andrà a cercare le province dei luoghi inseriti che hanno come regione "Calabria" la quale me li retituisce come xml. Clicca qui per lo screenshot del mio browser.

Ora e ecco i due file javascript uno chiamato ajax che gestisce la richiesta e la risposta e l'altro select che prepara la request e popola le select con i dati nell'xml di risposta:

ajax.js

/*
* Ritorna un nuovo XMLHttpRequest object, o false se il browser nn lo supporta
*/
function newXMLHttpRequest() {


var xmlreq = false;

// Crea un XMLHttpRequest object per browser nn Microsoft
if (window.XMLHttpRequest) {
xmlreq = new XMLHttpRequest();


} else if (window.ActiveXObject) {

try {
// Crea un XMLHttpRequest per le ultime versioni di InternetExplorer


xmlreq = new ActiveXObject("Msxml2.XMLHTTP");

} catch (e1) {

try {
// Crea un XMLHttpRequest per le vecchie versioni di InternetExplorerr


xmlreq = new ActiveXObject("Microsoft.XMLHTTP");

} catch (e2) {

// Impossibile creare un XMLHttpRequest

xmlreq = false;
}
}
}


return xmlreq;
}


/*
* Ritorna una funzione che aspetta fin quando l' XMLHttpRequest non abbia completato,
* quindi passa  l'XML response alla funzione che ha fatto la richiesta.


*/
function getReadyStateHandler(req, responseXmlHandler) {


// Ritorna una funziona anonima in ascolto all' XMLHttpRequest

return function () {

// Quando la richiesta è nello stato "complete"
if (req.readyState == 4) {


// Ed è andata a buon fine
if (req.status == 200) {


responseXmlHandler(req.responseXML);

} else {

alert("HTTP error "+req.status+": "+req.statusText);
}
}
}
}


select.js

//Funzione richiamata dall'evento on change
function changeSelect(changeName) {

var req = newXMLHttpRequest();//preparo un oggetto Xmlrequest

req.onreadystatechange = getReadyStateHandler(req, updateSelect);//gli dico qual'è la funzione che

//ascolta lo stato della richiesta req e la funzione da richiamare a richiesta completata


// preparo la richiesta
req.open("POST", "select.do", true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
if(changeName == "reg"){
req.send("value="+document.filtro.reg.value+"&select="+changeName);
}else{
if(changeName == "pro"){
req.send("value="+document.filtro.pro.value+"&select="+changeName);
}else{


req.send("value="+document.filtro.city.value+"&select="+changeName);
}
}
}


//funzione che fa il parsing dell'xml e popola la select specificata
function updateSelect(docXML) {


//ricavo il nome della selectoption sulla quale ooperare
var selectOption = docXML.getElementsByTagName("selectoption")[0];
var selectName = selectOption.getAttribute("name");


//A seconda della select
if (selectName == "Provincia"){


//svuoto la select
for (i=document.filtro.pro.options.length-1; i>=0;i--){


document.filtro.pro.remove(i);
}
for (i=document.filtro.city.options.length-1; i>=0;i--){//stessa cosa per la select della citta


document.filtro.city.remove(i);
}


var option = new Option("Citta", "Citta");// e gli metto la sola opzione Citta

document.filtro.city.options[0] = option;

for (i=document.filtro.cap.options.length-1; i>=0;i--){//Stessa cosa per cap

document.filtro.cap.remove(i);
}


option = new Option("Cap", "Cap");

document.filtro.cap.options[0] = option;

//prendo tutti gli elementi con tag option del tag selectoption in questione
var opts = selectOption.getElementsByTagName("option");
for (var I = 0 ; I < opts.length ; I++) {//li itero


var opt = opts[I];//Per ricavare nome e valore
var name = opt.getElementsByTagName("name")[0].firstChild.nodeValue;
var value = opt.getElementsByTagName("value")[0].firstChild.nodeValue;


option = new Option(value, name);//e li uso per caricare la select
document.filtro.pro.options[I] = option;


}
}
if (selectName == "Citta"){
for (i=document.filtro.city.options.length-1; i>=0;i--){


document.filtro.city.remove(i);
}
for (i=document.filtro.cap.options.length-1; i>=0;i--){


document.filtro.cap.remove(i);
}


option = new Option("Cap", "Cap");

document.filtro.cap.options[0] = option;

opts = selectOption.getElementsByTagName("option");
for ( I = 0 ; I < opts.length ; I++) {


opt = opts[I];
name = opt.getElementsByTagName("name")[0].firstChild.nodeValue;
value = opt.getElementsByTagName("value")[0].firstChild.nodeValue;


option = new Option(value, name);
document.filtro.city.options[I] = option;


}
}
if (selectName == "Cap"){


for (i=document.filtro.cap.options.length-1; i>=0;i--){

document.filtro.cap.remove(i);
}


opts = selectOption.getElementsByTagName("option");
for ( I = 0 ; I < opts.length ; I++) {


opt = opts[I];
name = opt.getElementsByTagName("name")[0].firstChild.nodeValue;
value = opt.getElementsByTagName("value")[0].firstChild.nodeValue;


option = new Option(value, name);
document.filtro.cap.options[I] = option;


}
}


}

nel javascript ho preferito commentare il codice in modo da essere più chiaro e semplice.

Con questo ho concluso spero abbiate capito. E vi auguro un buon test di quello che avete letto.

Se cliccate qui scaricate il tar.gz contenente il progetto netbeans con i sorgenti e i compilati e le librerie necessarie

Se avete dubbi, critiche o domande postate che vi rispondo....

3 commenti:

  1. Non funziona.....

    AVVERTENZA: StandardWrapperValve[action]: PWC1406: Servlet.service() for servlet action threw exception
    org.apache.jasper.JasperException: /lista.jsp(8,0) PWC6339: Cannot find a setter method for the attribute locale of the tag handler org.apache.struts.taglib.html.HtmlTag

    RispondiElimina
  2. Questo commento è stato eliminato dall'autore.

    RispondiElimina
  3. Come non detto..è bastato cambiare qualche riga di codice in lista.jsp ... ma non chiedere il perche' :-)

    <%@page contentType="text/html"%>
    <%@page pageEncoding="UTF-8"%>



    <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
    <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
    <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
    <%@ taglib uri="/WEB-INF/struts-nested.tld" prefix="nested" %>



    < h t m l : h t m l lang="true"> togliendo gli spazi
    in h t m l : h t m l
    .

    RispondiElimina