10. مثال ۰۸ – برچسبهای مرتبط با فهرستها
مثال زیر به برچسبهایی میپردازد که فهرستها را نمایش میدهند. ما قبلاً در مثال قبلی با آنها مواجه شدهایم: فهرست کشویی، چکباکسها و دکمههای رادیویی. فرم آزمون به شرح زیر خواهد بود:
![]() | ![]() |
10.1. پروژه NetBeans
پروژه NetBeans به این صورت است:
![]() |
- [1] اقدام و [2] نمای مرتبط است.
فایل [example/example.xml] برنامه را پیکربندی میکند:
<?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>
خطوط ۸–۹ نشان میدهند که فراخوانی URL [/example/Form.action]، نمای [/example/Form.JSP] را تولید میکند. بنابراین، اقدام [Form] مسئول ساخت قالب برای نما [Form.JSP] خواهد بود.
10.2. فایل پیامهای بینالمللیشده
فایل [messages.properties] حاوی پیامهای بینالمللی به شرح زیر است:
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
ویوی [Form.JSP] از این پیامها استفاده میکند.
10.3. نما [Form.JSP]
نما [Form.JSP] به شرح زیر است:
<%@ 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>
بیایید برچسبهای ورودی مختلف در فرم را بررسی کنیم:
- خط ۲۷: تگ <s:select>:
<s:select name="select1" list="{'vert','jaune','rouge'}" size="1" key="Form.select1"/>
این تگ کد HTML زیر را تولید میکند:
مقدار ویژگی list یک آرایه از رشتههای متنی است که برای تولید مقادیر و برچسبهای گزینهها استفاده میشود. قالب مرتبط، فیلد select1 از اقدام [Form] زیر است:
private String select1 = "jaune";
این فیلد، هم برای عملیات خواندن و هم برای نوشتن، به تگ با نام select1 متصل است. هنگام نوشتن، مقدار گزینه انتخابشده در فیلد select1 درج خواهد شد. هنگام خواندن، از مقدار فیلد select1 برای تعیین گزینه انتخابشده استفاده میشود. در اینجا، مقدار jaune در فیلد select1 برای انتخاب گزینه در تگ select1 که مقدار آن «yellow» است، استفاده میشود. به همین دلیل، در خط ۳، گزینه انتخاب میشود.
- خط ۲۸
<s:select name="select2" list="{'vert','jaune','rouge'}" size="3" key="Form.select2" multiple="true"/>
تفاوت بنیادین با تگ در خط ۲۷ وجود ندارد، به جز اینکه در اینجا انتخاب چندگانه است. بنابراین، مقدار ارسالشده یک آرایه از مقادیر است، یعنی مقادیر گزینههای انتخابشده. فیلد select2 از اکشن مرتبط با فرم به شرح زیر است:
private String[] select2 = new String[]{"vert", "rouge"};
این در واقع یک آرایه است. مقدار اولیه آن برای انتخاب گزینههایی استفاده میشود که مقادیرشان در آرایه موجود است.
- خط ۲۹
<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"/>
در اینجا، مقدار ویژگی list یک دیکشنری است که کلیدهای آن به عنوان مقدار برای گزینهها و مقادیر مرتبط با آن به عنوان برچسب برای گزینهها عمل میکنند. کد HTML تولید شده به شرح زیر است:
میدان مرتبط در action به شرح زیر است:
private String[] select3 = new String[]{"01", "03"};
بار دیگر، ما یک آرایه از مقادیر داریم زیرا تگ مربوطه یک عنصر چندگزینهای است. مقادیر اولیه این آرایه توضیح میدهد که چرا گزینههای سطرهای ۲ و ۴ در ابتدا انتخاب شدهاند.
- خط ۳۰
<s:select name="select4" list="dico" size="3" key="Form.select4" multiple="true"/>
در اینجا، گزینههای موجود در لیست توسط مدل نما ارائه میشوند که در این مورد بخشی از اکشن [Form] است:
private HashMap<String, String> dico = new HashMap<String, String>();
کلیدها در دیکشنری dico مقادیر گزینهها خواهند بود. مقادیر در دیکشنری dico برچسبهای گزینهها خواهند بود. فیلد select4 در اقدام به شرح زیر است:
private String[] select4 = new String[]{"1", "3"};
این یک آرایه از مقادیر است که مقادیر ارسالشده توسط تگ select4 را دریافت میکند.
- خط ۳۱
<s:select name="select5" list="couleurs" listKey="id" listValue="nom" size="3" key="Form.select5" multiple="true" />
فهرست گزینهها توسط فیلد couleurs که با ویژگی list تعریف شده است، تولید میشود. فیلد couleurs از اقدام [Form] به شرح زیر تعریف شده است:
private Couleur[] couleurs;
کلاس [Couleur] به شرح زیر تعریف شده است:
package example;
public class Couleur {
// fields
private String id;
private String nom;
// سازنده
public Couleur(){
}
// گیرندهها و تنظیمکنندهها
...
}
این دارای دو فیلد به نامهای id و nom است. در تگ select5، ما داریم listKey="id" و listValue="nom".. این بدان معناست که فیلد QZXW2HTMLPمیدان 001020ZQX بهعنوان مقدار یک گزینه و میدان nom بهعنوان برچسب عمل خواهد کرد. لطفاً توجه داشته باشید که مقادیر گزینهها ارسال میشوند. آنها به میدان زیر select5 ارسال خواهند شد:
private String[] select5 = new String[]{"1", "3"};
- خط ۳۲
<s:checkboxlist name="checkboxlist1" list="#{'01':'vert(01)','02':'jaune(02)','03':'rouge(03)','04':'blanc(04)','05':'noir(05)'}" key="Form.checkboxlist1"/>
این تگ کد HTML زیر را تولید خواهد کرد:
تمام کادرهای تیکدار با نام checkboxlist1 نامگذاری شدهاند. از آنجا که میتوان هر یک از آنها را تیکزده کرد، چندین پارامتر checkboxlist1 ممکن است ارسال شوند. بنابراین، فیلد checkboxlist1 در فرم باید از نوع آرایه باشد. ویژگی list در خط ۲۲ یک دیکشنری است که کلیدهای آن ویژگیهای value را برای چکباکسها تولید میکنند و مقادیر آن برچسبهای همان چکباکسها را تولید میکنند. میدان checkboxlist1 برای اقدام [Form] به شرح زیر است:
private String[] checkboxlist1 = new String[]{"01", "03"};
- خط ۳۳
<s:checkboxlist name="checkboxlist2" list="dico" key="Form.checkboxlist2"/>
این تگ به همان شیوهای عمل میکند که تگ select4 قبلاً مورد بحث قرار گرفت. فیلد مرتبط در اقدام به شرح زیر است:
private String[] checkboxlist2 = new String[]{"1", "3"};
- خط ۳۴
<s:checkboxlist name="checkboxlist3" list="couleurs" listKey="id" listValue="nom" key="Form.checkboxlist3" />
این تگ به همان شیوهای عمل میکند که تگ select5 قبلاً مورد بحث قرار گرفت. فیلد مرتبط checkboxlist3 در اقدام به شرح زیر است:
private String[] checkboxlist3 = new String[]{"1", "3"};
- خط ۳۵
<s:radio name="radio1" list="#{'01':'vert(01)','02':'jaune(02)','03':'rouge(03)','04':'blanc(04)','05':'noir(05)'}" key="Form.radio1"/>
این تگ از نظر اصول به همان شیوهای عمل میکند که تگ select3 که قبلاً مشاهده شد. کد HTML تولید شده به شرح زیر است:
تمام تگها نام یکسانی دارند: radio1. تنها یک دکمه رادیویی قابل انتخاب است. بنابراین، تنها یک مقدار ارسال میشود: مقدار دکمه رادیویی انتخابشده. کلیدهای موجود در دیکشنری list برای تولید ویژگیهای value برای دکمههای رادیویی استفاده میشوند، در حالی که مقادیر موجود در دیکشنری برای تولید برچسبهای مرتبط با این دکمهها به کار میروند. میدان مرتبط radio1 در action به شرح زیر است:
private String radio1="01";
- خط ۳۶
<s:radio name="radio2" list="dico" key="Form.radio2"/>
این تگ اصولاً به همان شیوه تگ select4 عمل میکند. فیلد radio2 مرتبط با اقدام به شرح زیر است:
private String radio2="1";
- خط ۳۷
<s:radio name="radio3" list="couleurs" listKey="id" listValue="nom" key="Form.radio3" />
این تگ به همان شیوه تگ select5 عمل میکند. فیلد مرتبط radio3 در اقدام به شرح زیر است:
private String radio3="1";
این بخش مربوط به قسمت saisie فرم است. همچنین یک بخش confirmation نیز وجود دارد که مشابه بخش قبلی است: این بخش مقادیر ارسالشده را تأیید میکند. ما فقط در مورد خطوط زیر توضیح میدهیم:
<tr>
<td><s:text name="Form.select2"/></td>
<td><s:property value="select2SelectedValues"/>
</tr>
که از نظر بصری با موارد زیر مطابقت دارد:
متن موجود در سلول سمت چپ از فایل [messages.properties] گرفته شده است:
Form.select2=2-select2 (multiple=true, size=3)
متن در سلول سمت راست توسط روش getSelect2SelectedValues از اقدام [Form] تولید شده است:
// مقادیر انتخابشده از فهرستهای کشویی
public String getSelect2SelectedValues() {
return getArrayValue(select2);
}
// متدهای ابزار
public String getArrayValue(String[] values) {
String result = "";
for (String value : values) {
result += " " + value;
}
return result;
}
روش getSelect2SelectedValues مقادیر جدول select2 را به صورت یک رشتهٔ کاراکتری بازمیگرداند.
10.4. عمل [Form]
هنگام بحث درباره نما [Form.JSP]، ما حوزههای اقدام مرتبط [Form] را تشریح کردیم. کد اقدام [Form] به شرح زیر است:
package example;
import com.opensymphony.xwork2.ActionSupport;
import java.util.HashMap;
public class Form extends ActionSupport {
// fields of the form
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;
// سازنده بدون پارامتر
public Form() {
// ابتداییسازی دیکشنری رنگ
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)");
// ابتداییسازی آرایهٔ اشیاء Color
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++;
}
}
// مقادیر انتخابشده از لیستهای کشویی
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);
}
// متدهای ابزار
public String getArrayValue(String[] values) {
String result = "";
for (String value : values) {
result += " " + value;
}
return result;
}
// متدهای get و set
...
}
در این اقدام، متدی با نام execute وجود ندارد. بنابراین متد execute از کلاس والد ActionSupport اجرا میشود. این متد هیچ کاری انجام نمیدهد و صرفاً کلید ناوبری SUCCESS را برمیگرداند.
10.5. آزمایشها
از خوانندگان دعوت میشود تا برنامه کاربردی [exemple-08] را آزمایش کنند.


