10. Voorbeeld 08 - Tags voor lijsten
Het volgende voorbeeld gaat over tags waarmee lijsten worden weergegeven. We zijn deze al tegengekomen in het vorige voorbeeld: de vervolgkeuzelijst, de selectievakjes en de keuzerondjes. Het testformulier ziet er als volgt uit:
![]() | ![]() |
10.1. Het NetBeans-project
Het NetBeans-project ziet er als volgt uit:
![]() |
- in [1] de actie en in [2] de bijbehorende weergave.
Het bestand [example/example.xml] configureert de applicatie:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="example" namespace="/example" extends="struts-default">
<action name="Form" class="example.Form">
<result name="success">/example/Form.JSP</result>
</action>
</package>
</struts>
Uit de regels 8-9 blijkt dat een aanroep van URL [/example/Form.action] de weergave [/example/Form.JSP] genereert. De actie [Form] zorgt er dus voor dat het model van de weergave [Form.JSP] wordt opgebouwd.
10.2. Het bestand met geïnternationaliseerde berichten
Het bestand [messages.properties] met de geïnternationaliseerde berichten ziet er als volgt uit:
Form.francais=Fran\u00E7ais
Form.anglais=Anglais
Form.titre=Struts 2 - les tags \u00E0 valeurs multiples
Form.message=Struts 2 - les tags \u00E0 valeurs multiples
Form.langues=langues
Form.select1=1-select1 (multiple=false, size=1)
Form.select2=2-select2 (multiple=true, size=3)
Form.select3=3-select3 (multiple=true, size=3)
Form.select4=4-select4 (multiple=true, size=3)
Form.select5=5-select5 (multiple=true, size=3)
Form.checkboxlist1=6-checkboxlist1
Form.checkboxlist2=7-checkboxlist2
Form.checkboxlist3=8-checkboxlist3
Form.radio1=9-radio1
Form.radio2=10-radio2
Form.radio3=11-radio3
Form.submitText=Valider
Confirmation.message=Confirmation des valeurs saisies
Confirmation.champ=champ
Confirmation.valeur=valeur
Confirmation.select1=1-select1 (multiple=false, size=1)
Confirmation.select2=2-select2 (multiple=false, size=3)
Confirmation.select3=3-select3 (multiple=true, size=3)
Confirmation.select4=4-select4 (multiple=true, size=3)
Confirmation.select5=5-select5 (multiple=true, size=3)
Confirmation.checkboxlist1=6-checkboxlist1
Confirmation.checkboxlist2=7-checkboxlist2
Confirmation.checkboxlist3=8-checkboxlist3
Confirmation.radio1=9-radio1
Confirmation.radio2=10-radio2
Confirmation.radio3=11-radio3
De weergave [Form.JSP] maakt gebruik van deze berichten.
10.3. De weergave [Form.JSP]
De weergave [Form.JSP] is als volgt:
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title><s:text name="Form.titre"/></title>
<s:head/>
</head>
<body background="<s:url value="/ressources/standard.jpg"/>">
<h2><s:text name="Form.message"/></h2>
<h3><s:text name="Form.langues"/></h3>
<ul>
<li>
<s:url id="URL" action="Form">
<s:param name="request_locale">en</s:param>
</s:url>
<s:a href="%{URL}"><s:text name="Form.anglais"/></s:a>
</li>
<li>
<s:url id="URL" action="Form">
<s:param name="request_locale">fr</s:param>
</s:url>
<s:a href="%{URL}"><s:text name="Form.francais"/></s:a>
</li>
</ul>
<s:form name="formulaire">
<s:select name="select1" list="{'vert','jaune','rouge'}" size="1" key="Form.select1"/>
<s:select name="select2" list="{'vert','jaune','rouge'}" size="3" key="Form.select2" multiple="true"/>
<s:select name="select3" list="#{'01':'vert(01)','02':'jaune(02)','03':'rouge(03)','04':'blanc(04)','05':'noir(05)'}" size="3" key="Form.select3" multiple="true"/>
<s:select name="select4" list="dico" size="3" key="Form.select4" multiple="true"/>
<s:select name="select5" list="couleurs" listKey="id" listValue="nom" size="3" key="Form.select5" multiple="true" />
<s:checkboxlist name="checkboxlist1" list="#{'01':'vert(01)','02':'jaune(02)','03':'rouge(03)','04':'blanc(04)','05':'noir(05)'}" key="Form.checkboxlist1"/>
<s:checkboxlist name="checkboxlist2" list="dico" key="Form.checkboxlist2"/>
<s:checkboxlist name="checkboxlist3" list="couleurs" listKey="id" listValue="nom" key="Form.checkboxlist3" />
<s:radio name="radio1" list="#{'01':'vert(01)','02':'jaune(02)','03':'rouge(03)','04':'blanc(04)','05':'noir(05)'}" key="Form.radio1"/>
<s:radio name="radio2" list="dico" key="Form.radio2"/>
<s:radio name="radio3" list="couleurs" listKey="id" listValue="nom" key="Form.radio3" />
<s:submit key="Form.submitText" name="submitText"/>
</s:form>
<hr/>
<h2><s:text name="Confirmation.message"/></h2>
<table border="1">
<tr>
<th><s:text name="Confirmation.champ"/></th>
<th><s:text name="Confirmation.valeur"/></th>
</tr>
<tr>
<td><s:text name="Form.select1"/></td>
<td><s:property value="select1"/>
</tr>
<tr>
<td><s:text name="Form.select2"/></td>
<td><s:property value="select2SelectedValues"/>
</tr>
<tr>
<td><s:text name="Form.select3"/></td>
<td><s:property value="select3SelectedValues"/>
</tr>
<tr>
<td><s:text name="Form.select4"/></td>
<td><s:property value="select4SelectedValues"/>
</tr>
<tr>
<td><s:text name="Form.select5"/></td>
<td><s:property value="select5SelectedValues"/>
</tr>
<tr>
<td><s:text name="Form.checkboxlist1"/></td>
<td><s:property value="checkboxlist1SelectedValues"/>
</tr>
<tr>
<td><s:text name="Form.checkboxlist2"/></td>
<td><s:property value="checkboxlist2SelectedValues"/>
</tr>
<tr>
<td><s:text name="Form.checkboxlist3"/></td>
<td><s:property value="checkboxlist3SelectedValues"/>
</tr>
<tr>
<td><s:text name="Form.radio1"/></td>
<td><s:property value="radio1"/>
</tr>
<tr>
<td><s:text name="Form.radio2"/></td>
<td><s:property value="radio2"/>
</tr>
<tr>
<td><s:text name="Form.radio3"/></td>
<td><s:property value="radio3"/>
</tr>
</table>
</body>
</html>
Laten we de verschillende invoertags van het formulier eens bekijken:
- regel 27: de tag <s:select>:
<s:select name="select1" list="{'vert','jaune','rouge'}" size="1" key="Form.select1"/>
Deze tag genereert de volgende HTML-code:
De waarde van het attribuut list is een array van tekenreeksen die wordt gebruikt om de waarden en labels van de opties te genereren. Het bijbehorende model is het veld select1 van de volgende actie [Form]:
private String select1 = "jaune";
Dit veld is gekoppeld aan de tag met de naam select1, zowel voor lezen als voor schrijven. Bij het schrijven wordt de waarde van de geselecteerde optie in het veld select1 ingevoerd. Bij het lezen wordt de waarde van het veld select1 gebruikt om de geselecteerde optie te bepalen. Hier wordt de waarde jaune van het veld select1 gebruikt om de optie van de tag select1 te selecteren, die de waarde ‘geel’ heeft. Daarom is de optie in regel 3 geselecteerd.
- regel 28
<s:select name="select2" list="{'vert','jaune','rouge'}" size="3" key="Form.select2" multiple="true"/>
Er is geen fundamenteel verschil met de tag in regel 27, behalve dat hier meerdere opties zijn geselecteerd. De verzonden waarde is dus een array van waarden, namelijk die van de geselecteerde opties. Het veld select2 van de actie die aan het formulier is gekoppeld, is als volgt:
private String[] select2 = new String[]{"vert", "rouge"};
Dit is inderdaad een array. De beginwaarde ervan wordt gebruikt om de opties te selecteren waarvan de waarden in de array voorkomen.
- regel 29
<s:select name="select3" list="#{'01':'vert(01)','02':'jaune(02)','03':'rouge(03)','04':'blanc(04)','05':'noir(05)'}" size="3" key="Form.select3" multiple="true"/>
Hier is de waarde van het attribuut list een woordenboek waarvan de sleutels dienen als waarden voor de opties en de bijbehorende waarden dienen als labels voor de opties. De gegenereerde HTML-code is als volgt:
Het bijbehorende veld in de actie is als volgt:
private String[] select3 = new String[]{"01", "03"};
We hebben opnieuw een array met waarden, omdat de bijbehorende tag een meerkeuzevraag is. De beginwaarden van de array verklaren waarom de opties in de regels 2 en 4 aanvankelijk zijn geselecteerd.
- regel 30
<s:select name="select4" list="dico" size="3" key="Form.select4" multiple="true"/>
Hier worden de opties in de lijst aangeleverd door het weergavemodel, dat in dit geval deel uitmaakt van de actie [Form]:
private HashMap<String, String> dico = new HashMap<String, String>();
De sleutels van het woordenboek dico zijn de waarden van de opties. De waarden van het woordenboek dico zijn de benamingen van de opties. Het veld select4 van de actie is als volgt:
private String[] select4 = new String[]{"1", "3"};
Dit is een tabel met waarden waarin de waarden worden opgeslagen die door de tag select4 worden verzonden.
- regel 31
<s:select name="select5" list="couleurs" listKey="id" listValue="nom" size="3" key="Form.select5" multiple="true" />
De lijst met opties wordt gegenereerd door het veld couleurs, dat is gedefinieerd door het attribuut list. Het veld couleurs van de actie [Form] is als volgt gedefinieerd:
private Couleur[] couleurs;
De klasse [Couleur] is als volgt gedefinieerd:
package example;
public class Couleur {
// velden
private String id;
private String nom;
// constructor
public Couleur(){
}
// getters en setters
...
}
Het bevat twee velden met de namen id en nom. In de tag select5 staat listKey="id" listValue="nom". Dit betekent dat het veld id als waarde voor een optie zal dienen en het veld nom als omschrijving. Ter herinnering: het zijn de waarden van de opties die worden geboekt. Deze worden geboekt in het volgende veld select5:
private String[] select5 = new String[]{"1", "3"};
- regel 32
<s:checkboxlist name="checkboxlist1" list="#{'01':'vert(01)','02':'jaune(02)','03':'rouge(03)','04':'blanc(04)','05':'noir(05)'}" key="Form.checkboxlist1"/>
Deze tag genereert de volgende HTML-code:
Alle selectievakjes hebben de naam checkboxlist1. Aangezien elk vakje kan worden aangevinkt, kunnen er meerdere checkboxlist1-parameters worden verzonden. Het veld checkboxlist1 in het model moet daarom van het type array zijn. Het attribuut list op regel 22 is een woordenboek waarvan de sleutels de attributen value van de selectievakjes genereren en de waarden de labels van diezelfde selectievakjes. Het veld checkboxlist1 van de actie [Form] is als volgt:
private String[] checkboxlist1 = new String[]{"01", "03"};
- regel 33
<s:checkboxlist name="checkboxlist2" list="dico" key="Form.checkboxlist2"/>
Deze tag werkt op dezelfde manier als de eerder besproken tag select4. Het bijbehorende veld in de actie is als volgt:
private String[] checkboxlist2 = new String[]{"1", "3"};
- regel 34
<s:checkboxlist name="checkboxlist3" list="couleurs" listKey="id" listValue="nom" key="Form.checkboxlist3" />
Deze tag werkt op dezelfde manier als de eerder besproken tag select5. Het bijbehorende veld checkboxlist3 in de actie is als volgt:
private String[] checkboxlist3 = new String[]{"1", "3"};
- regel 35
<s:radio name="radio1" list="#{'01':'vert(01)','02':'jaune(02)','03':'rouge(03)','04':'blanc(04)','05':'noir(05)'}" key="Form.radio1"/>
Deze tag werkt in principe net als de eerder besproken tag select3. De gegenereerde HTML-code is als volgt:
Alle tags hebben dezelfde naam: radio1. Er kan slechts één keuzerondje worden aangevinkt. Er wordt dus slechts één waarde verzonden, namelijk die van het aangevinkte keuzerondje. De sleutels van het woordenboek list worden gebruikt om de attributen value van de keuzerondjes te genereren, terwijl de waarden van het woordenboek worden gebruikt om de bijbehorende labels voor deze keuzerondjes te genereren. Het bijbehorende veld radio1 in de actie is het volgende:
private String radio1="01";
- regel 36
<s:radio name="radio2" list="dico" key="Form.radio2"/>
Deze tag werkt in principe hetzelfde als de tag select4. Het bij de actie gekoppelde veld radio2 is het volgende:
private String radio2="1";
- regel 37
<s:radio name="radio3" list="couleurs" listKey="id" listValue="nom" key="Form.radio3" />
Deze tag werkt in principe hetzelfde als de tag select5. Het bijbehorende veld radio3 in de actie is het volgende:
private String radio3="1";
Tot zover het gedeelte saisie van het formulier. Er is ook een gedeelte confirmation dat vergelijkbaar is met dat van het formulier uit het vorige voorbeeld: het bevestigt de verzonden waarden. We zullen alleen de volgende regels toelichten:
<tr>
<td><s:text name="Form.select2"/></td>
<td><s:property value="select2SelectedValues"/>
</tr>
wat visueel overeenkomt met het volgende:
De tekst in de linkercel is afkomstig uit het bestand [messages.properties]:
Form.select2=2-select2 (multiple=true, size=3)
De tekst in de cel rechts is gegenereerd door de methode getSelect2SelectedValues van de actie [Form]:
// geselecteerde waarden in vervolgkeuzelijsten
public String getSelect2SelectedValues() {
return getArrayValue(select2);
}
// hulpprogramma's
public String getArrayValue(String[] values) {
String result = "";
for (String value : values) {
result += " " + value;
}
return result;
}
De methode getSelect2SelectedValues zet de waarden van de tabel select2 om in een tekenreeks.
10.4. De actie [Form]
In onze toelichting bij het scherm [Form.JSP] hebben we de velden van de bijbehorende actie [Form] besproken. De code van de actie [Form] is als volgt:
package example;
import com.opensymphony.xwork2.ActionSupport;
import java.util.HashMap;
public class Form extends ActionSupport {
// formuliervelden
private String select1 = "jaune";
private String[] select2 = new String[]{"vert", "rouge"};
private String[] select3 = new String[]{"01", "03"};
private String[] select4 = new String[]{"1", "3"};
private String[] select5 = new String[]{"1", "3"};
private HashMap<String, String> dico = new HashMap<String, String>();
private Couleur[] couleurs;
private String[] checkboxlist1 = new String[]{"01", "03"};
private String[] checkboxlist2 = new String[]{"1", "3"};
private String[] checkboxlist3 = new String[]{"1", "3"};
private String radio1="01";
private String radio2="1";
private String radio3="1";
private String submitText;
// constructor zonder parameters
public Form() {
// kleurenwoordenboek initialiseren
dico.put("1", "vert(1)");
dico.put("2", "jaune(2)");
dico.put("3", "bleu(3)");
dico.put("4", "rouge(4)");
dico.put("5", "blanc(5)");
// initialisatie van de array met Kleur-objecten
couleurs = new Couleur[dico.size()];
int i = 0;
for (String key : dico.keySet()) {
couleurs[i] = new Couleur();
couleurs[i].setId(key);
couleurs[i].setNom(dico.get(key));
i++;
}
}
// geselecteerde waarden in vervolgkeuzelijsten
public String getSelect2SelectedValues() {
return getArrayValue(select2);
}
public String getSelect3SelectedValues() {
return getArrayValue(select3);
}
public String getSelect4SelectedValues() {
return getArrayValue(select4);
}
public String getSelect5SelectedValues() {
return getArrayValue(select5);
}
public String getCheckboxlist1SelectedValues() {
return getArrayValue(checkboxlist1);
}
public String getCheckboxlist2SelectedValues() {
return getArrayValue(checkboxlist2);
}
public String getCheckboxlist3SelectedValues() {
return getArrayValue(checkboxlist3);
}
// hulpprogramma's
public String getArrayValue(String[] values) {
String result = "";
for (String value : values) {
result += " " + value;
}
return result;
}
// getters en setters
...
}
Er is geen methode execute in deze actie te vinden. Daarom wordt de methode execute van de bovenliggende klasse ActionSupport uitgevoerd. Deze methode doet niets en geeft alleen de navigatiesleutel SUCCESS terug.
10.5. De tests
De lezer wordt uitgenodigd om de toepassing [exemple-08] te testen.


