Struts2讲义22(转载)
复杂表单标签使用介绍
技术要点
本节代码具体介绍各个复杂表单标签的使用方式。这些标签在不使用 Struts2 的情况下都是用基础表单标签和 JavaScript 代码联合起来使用才能达到这些标签的效果。
复杂表单标签使用。
复杂表单标签功能演示。
演示代码
使用 doubleselect 和 optiontransferselect 标签需要显示的材料类别类文件代码:
- <!-------------- 文件名: Item.java ------------>
- public class Item implements java.io.Serializable {
- private int itemId;
- private String item;
- …………
- public int getItemId() {
- return itemId;
- }
- public void setItemId(int itemId) {
- this.itemId = itemId;
- }
- public String getItem() {
- return this.item;
- }
- public void setItem(String item) {
- this.item = item;
- }
- }
<!-------------- 文件名: Item.java ------------>
public class Item implements java.io.Serializable {
private int itemId;
private String item;
…………
public int getItemId() {
return itemId;
}
public void setItemId(int itemId) {
this.itemId = itemId;
}
public String getItem() {
return this.item;
}
public void setItem(String item) {
this.item = item;
}
}
使用 doubleselect 和 optiontransferselect 标签需要显示的材料类文件代码:
- <!----------- 文件名: Material.java ------------>
- public class Material implements java.io.Serializable {
- private int materialId;
- private int itemid;
- private String material;
- …………
- public int getMaterialId() {
- return this.materialId;
- }
- public void setMaterialId(int materialId) {
- this.materialId = materialId;
- }
- ……………
- public String getMaterial() {
- return this.material;
- }
- public void setMaterial(String material) {
- this.material = material;
- }
- }
<!----------- 文件名: Material.java ------------>
public class Material implements java.io.Serializable {
private int materialId;
private int itemid;
private String material;
…………
public int getMaterialId() {
return this.materialId;
}
public void setMaterialId(int materialId) {
this.materialId = materialId;
}
……………
public String getMaterial() {
return this.material;
}
public void setMaterial(String material) {
this.material = material;
}
}
使用 doubleselect 和 optiontransferselect 标签是的 Action 文件代码:
- <!------------ 文件名: ComplexFormTagAction.java ---------->
- public class ComplexFormTagAction extends ActionSupport {
- // 级联第一个下拉框数据
- private List<Item> itemList;
- // 级联第二个下拉框数据
- private Map<Integer, List<Material>> materialMap;
- // 左边材料数据
- private String[] leftMaterials;
- // 右边材料数据
- private String[] rightMaterials;
- public String execute() throws Exception {
- itemList = new ArrayList<Item>();
- // 循环新建 10 个类别
- for (int j = 0; j < 10; j++) {
- Item item = new Item();
- item.setItemId(j + 1);
- item.setItem(" 类别 " + (j + 1));
- itemList.add(item);
- }
- materialMap = new HashMap<Integer, List<Material>>();
- // 循环新建每个类别中的 10 个材料
- for (int j = 0; j < 10; j++) {
- List<Material> materialList = new ArrayList<Material>();
- for (int i = 0; i < 10; i++) {
- Material material = new Material();
- material.setItemid(i + 1);
- material.setMaterialId(i);
- material.setMaterial(" 类别 " + (j + 1)+"-->"+" 材料 "+(i + 1));
- materialList.add(material);
- }
- materialMap.put((j + 1), materialList);
- }
- int tempCount;
- ArrayList<Material> leftList = new ArrayList<Material>();
- for (int i = 0; i < 10; i++) {
- Material leftMaterial = new Material();
- leftMaterial.setMaterialId(i + 1);
- leftMaterial.setMaterial(" 材料 " + (i + 1));
- leftList.add(leftMaterial);
- }
- tempCount = 10;
- ArrayList<Material> rightList = new ArrayList<Material>();
- for (int i = 0; i < 10; i++) {
- Material rightMaterial = new Material();
- rightMaterial.setMaterialId(i + 1);
- rightMaterial.setMaterial(" 材料 " + (tempCount + i + 1));
- rightList.add(rightMaterial);
- }
- getRequest().setAttribute("rightList", rightList);
- getRequest().setAttribute("leftList", leftList);
- return SUCCESS ;
- }
- private HttpServletRequest getRequest() {
- return ServletActionContext.getRequest();
- }
- public Map<Integer, List<Material>> getMaterialMap() {
- return materialMap;
- }
- public void setMaterialMap(Map<Integer, List<Material>> materialMap) {
- this .materialMap = materialMap;
- }
- …………
- public String[] getRightMaterials() {
- return rightMaterials;
- }
- public void setRightMaterials(String[] rightMaterials) {
- this .rightMaterials = rightMaterials;
- }
- }
<!------------ 文件名: ComplexFormTagAction.java ---------->
public class ComplexFormTagAction extends ActionSupport {
// 级联第一个下拉框数据
private List<Item> itemList;
// 级联第二个下拉框数据
private Map<Integer, List<Material>> materialMap;
// 左边材料数据
private String[] leftMaterials;
// 右边材料数据
private String[] rightMaterials;
public String execute() throws Exception {
itemList = new ArrayList<Item>();
// 循环新建 10 个类别
for (int j = 0; j < 10; j++) {
Item item = new Item();
item.setItemId(j + 1);
item.setItem(" 类别 " + (j + 1));
itemList.add(item);
}
materialMap = new HashMap<Integer, List<Material>>();
// 循环新建每个类别中的 10 个材料
for (int j = 0; j < 10; j++) {
List<Material> materialList = new ArrayList<Material>();
for (int i = 0; i < 10; i++) {
Material material = new Material();
material.setItemid(i + 1);
material.setMaterialId(i);
material.setMaterial(" 类别 " + (j + 1)+"-->"+" 材料 "+(i + 1));
materialList.add(material);
}
materialMap.put((j + 1), materialList);
}
int tempCount;
ArrayList<Material> leftList = new ArrayList<Material>();
for (int i = 0; i < 10; i++) {
Material leftMaterial = new Material();
leftMaterial.setMaterialId(i + 1);
leftMaterial.setMaterial(" 材料 " + (i + 1));
leftList.add(leftMaterial);
}
tempCount = 10;
ArrayList<Material> rightList = new ArrayList<Material>();
for (int i = 0; i < 10; i++) {
Material rightMaterial = new Material();
rightMaterial.setMaterialId(i + 1);
rightMaterial.setMaterial(" 材料 " + (tempCount + i + 1));
rightList.add(rightMaterial);
}
getRequest().setAttribute("rightList", rightList);
getRequest().setAttribute("leftList", leftList);
return SUCCESS ;
}
private HttpServletRequest getRequest() {
return ServletActionContext.getRequest();
}
public Map<Integer, List<Material>> getMaterialMap() {
return materialMap;
}
public void setMaterialMap(Map<Integer, List<Material>> materialMap) {
this .materialMap = materialMap;
}
…………
public String[] getRightMaterials() {
return rightMaterials;
}
public void setRightMaterials(String[] rightMaterials) {
this .rightMaterials = rightMaterials;
}
}
复杂表单标签的 JSP 文件:
- <!------------ 文件名: complexFormTag.jsp---------------->
- <%@ taglib prefix="s" uri="/struts-tags"%>
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <title> 复杂表单标签使用范例 </title>
- <s:head />
- </head>
- <body>
- <h3 align="left">
- 复杂表单标签使用范例(不使用 Struts2 时需要结合 JavaScript 和 HTML 标签共同开发的功能)
- </h3>
- <h3 align="left">
- combobox 标签使用范例
- </h3>
- <p>
- <s:combobox label=" 材料 " name="material" readonly="false"
- headerValue="" headerKey="0" list="{' 进户门套油漆 ', ' 踢脚线 ', ' 大理石 ', ' 吊顶 '}" />
- </p>
- <h3 align="left">
- doubleselect 标签使用范例
- </h3>
- <p>
- <s:form name="doubleselectExample">
- <s:doubleselect label=" 材料 " headerValue="" headerKey="0"
- list="itemList" listKey="itemId" listValue="item"
- doubleName="materialId" doubleList="materialMap.get(top.itemId)"
- doubleListKey="materialId" doubleListValue="material" />
- </s:form>
- </p>
- <h3 align="left">
- datetimepicker 标签使用范例
- </h3>
- <p>
- <s:datetimepicker label=" 日历 " name="calendar" value="today"
- toggleType="plain" toggleDuration="300" language="zh_CN" type="date"
- displayWeeks="5" displayFormat="dd/MM/yyyy" formatLength="long" />
- </p>
- <h3 align="left">
- optiontransferselect 标签使用范例
- </h3>
- <p>
- <s:optiontransferselect label=" 材料 " name="leftMaterials"
- leftTitle=" 已选择材料 " list="#request.leftList" listKey="materialId"
- listValue="material" multiple="true" headerKey="headerKey"
- headerValue=" 请选择 " emptyOption="false" allowUpDownOnLeft="true"
- rightTitle=" 未选择材料 " doubleList="#request.rightList"
- doubleListKey="materialId" doubleListValue="material"
- doubleName="rightMaterials" doubleHeaderKey="doubleHeaderKey"
- doubleHeaderValue=" 请选择 " doubleEmptyOption="false"
- doubleMultiple="true" allowUpDownOnRight="true" />
- </p>
- <h3 align="left">
- updownselect 标签使用范例
- </h3>
- <p>
- <s:form name="updownselectExample">
- <s:updownselect
- list="#{'01':' 进户门套油漆 ','02':' 踢脚线 ','03':' 大理石 ','04':' 吊顶 '}"
- name="material"
- headerKey="-1"
- headerValue=" 选择 "
- moveUpLabel="up" moveDownLabel="down" selectAllLabel="all"
- />
- </s:form>
- </p>
- </body>
- </html>
<!------------ 文件名: complexFormTag.jsp---------------->
<%@ taglib prefix="s" uri="/struts-tags"%>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title> 复杂表单标签使用范例 </title>
<s:head />
</head>
<body>
<h3 align="left">
复杂表单标签使用范例(不使用 Struts2 时需要结合 JavaScript 和 HTML 标签共同开发的功能)
</h3>
<h3 align="left">
combobox 标签使用范例
</h3>
<p>
<s:combobox label=" 材料 " name="material" readonly="false"
headerValue="" headerKey="0" list="{' 进户门套油漆 ', ' 踢脚线 ', ' 大理石 ', ' 吊顶 '}" />
</p>
<h3 align="left">
doubleselect 标签使用范例
</h3>
<p>
<s:form name="doubleselectExample">
<s:doubleselect label=" 材料 " headerValue="" headerKey="0"
list="itemList" listKey="itemId" listValue="item"
doubleName="materialId" doubleList="materialMap.get(top.itemId)"
doubleListKey="materialId" doubleListValue="material" />
</s:form>
</p>
<h3 align="left">
datetimepicker 标签使用范例
</h3>
<p>
<s:datetimepicker label=" 日历 " name="calendar" value="today"
toggleType="plain" toggleDuration="300" language="zh_CN" type="date"
displayWeeks="5" displayFormat="dd/MM/yyyy" formatLength="long" />
</p>
<h3 align="left">
optiontransferselect 标签使用范例
</h3>
<p>
<s:optiontransferselect label=" 材料 " name="leftMaterials"
leftTitle=" 已选择材料 " list="#request.leftList" listKey="materialId"
listValue="material" multiple="true" headerKey="headerKey"
headerValue=" 请选择 " emptyOption="false" allowUpDownOnLeft="true"
rightTitle=" 未选择材料 " doubleList="#request.rightList"
doubleListKey="materialId" doubleListValue="material"
doubleName="rightMaterials" doubleHeaderKey="doubleHeaderKey"
doubleHeaderValue=" 请选择 " doubleEmptyOption="false"
doubleMultiple="true" allowUpDownOnRight="true" />
</p>
<h3 align="left">
updownselect 标签使用范例
</h3>
<p>
<s:form name="updownselectExample">
<s:updownselect
list="#{'01':' 进户门套油漆 ','02':' 踢脚线 ','03':' 大理石 ','04':' 吊顶 '}"
name="material"
headerKey="-1"
headerValue=" 选择 "
moveUpLabel="up" moveDownLabel="down" selectAllLabel="all"
/>
</s:form>
</p>
</body>
</html>
功能演示如图 5.22 、图 5.23 和图 5.24 。
图 5.22 复杂表单标签范例图 1
图 5.23 复杂表单标签范例图 2
图 5.24 复杂表单标签范例图 3
代码解释
( 1 ) combobox 标签的功能是显示一个可以让用户选择的复选框和一个可以让用户输入的文本输入框组合。这两个表单标签在 HTTP 请求中同时被指定同一个请求参数。 list 属性是指定一个下拉框选择内容的数据集合。 headerValue 和 headerKey 属性和前述的标签中属性功能相同。该标签具有一个 readonly 属性,它是表明文本输入框中是否允许输入文本,如果 readonly 属性值为“ true ”则不允许用户输入,只能查看该文本输入框中显示的内容。
( 2 ) doubleselect 标签的功能是提供两个有级联关系的下拉框。用户选中第一个下拉框中某选项,则第二个下拉框中选项是根据第一个下拉框被选中的某选项内容来决定它自己的下拉框选项内容。(由于该标签名字中包含“ double ”,因此它只提供两个级联关系的下拉框。如果开发者想利用该标签开发多个级联关系下拉框,则还需要自己编写 JavaScript 或 Java 代码联合使用该标签开发。笔者很希望 Struts2 的设计者在以后的版本中能提供一个 multiselect 标签,这样开发者就可以直接使用该标签来快速开发多个级联关系下拉框。)
该标签属性有很多。其中 list 属性是指定第一个下拉框中选项的数据集合。 listKey 和 listValue 属性是分别指定第一个下拉框中的 value 和页面上显示的内容。 doubleList 是指定第二个下拉框中选项的数据集合。 doubleListKey 和 doubleListValue 属性是分别指定第二个下拉框中的 value 和页面上显示的内容。 doubleName 是第二个下拉框的名字属性。其它诸如 headerKey 和 headerValue 属性都和之前记述的标签中属性相同。
在本示例中,笔者先定义了两个有级联关系的 Java 类,一个是材料类别,另一个是材料。每个材料类别分别拥有多种材料。因此第一个下拉框中选项都是类别数据,第二个下拉框中选线都是材料数据。用户选中一个类别,则相应第二个下拉框根据这个类别显示该类别中所包含的所有材料选项。图 5.22 中已经演示给读者看,选中“类别 2 ”,然后第二个下拉框中材料选项都是“类别 2 ”的材料,然后再选中“材料 5 ”。在 Action 代码中,笔者也利用循环新建了 10 个类别和每个类别拥有的 10 个材料。然后将类别放入一个 list 类型数据集合中,材料放在 map 类型数据集合中,该 map 集合的 key 就是类别的 id 。然后在 JSP 中利用 OGNL 表达式配合 doubleselect 标签来将这两个集合的数据在级联下拉框中显示。
注意: JSP 中有“ materialMap.get(top.itemId) ”这行代码。其中的 top 其实返回的是材料类别 map 集合的 value 即材料 list 集合中的材料类对象实例,而不是材料 list 集合。而且 在使用该标签时候,该标签一定要包含在 form 表单中,否则功能不会实现。
( 3 ) datetimepicker 标签 的功能是显示一个可以选择时间日期的选择框。如果不使用 Struts2 的话,以前都是用 JavaScript 来完成这个选择框实现工作。现在 Struts2 底层已经集成了该选择框,开发者只要使用该标签就能完成开发工作,节省了大量时间。
该标签属性也很多。 value 属性可以指定具体的时间日期,也可以用“ today ”表示当前日期。 type 属性只能是“ date ”和“ time ”,分别表示是日期选择还是时间选择。 language 属性是指定选择的国家文字类型,比如在该示例中的“ zh_CN ”表明显示的是简体中文。 displayWeeks 属性表明日历显示的星期数,一般如果要把一个月的日期都显示,需要显示星期数为 5 ,所以该示例中笔者对该属性的值是赋为 5 。 displayFormat 属性指定日期显示格式。 formateLength 属性则表明显示的日期格式类型,它一共有四个可以赋给它的值,分别为 long 、 short 、 medium 、 full 。 toggleType 和 toggleDuration 属性都是和日期选择框有关。 toggleType 属性是指定日期选择框的显示、关闭方式。它也有四个可以赋的值,分别是 plain 、 wipe 、 explode 、 fade 。示例中笔者用的是 plain 。而 toggleDuration 属性是指定日期选择框显示、关闭的时间间隔,单位是毫秒。示例中定义的是 300 即日期选择框显示、关闭时间是 300 毫秒。
图 5.25 是日期选择框显示的效果。读者可以看到显示了 2008 年 7 月的日历,白色显示的 26 号即笔者写作这章的当前日期。选择框最下方是可以让用户选择的纪年。
图 5.25 plain 型的日期选择框显示图
注意:在使用该标签时候, JSP 中一定要显示定义在下一小节中将会介绍的 head 标签。因为 head 标签是调用了某些 AJAX 的框架 dojo 定义的文件,该标签显示的日期格式等其实都是由 dojo 来实现的。所以不使用 head 标签,该标签就不能正常在页面上显示日期选择。
( 4 ) optiontransferselect 标签的功能是提供两个可以左右转移以及下拉的列表项。该标签中提供了很多上下左右移动选择项的功能。而且还可以进行多项选择项移动。以前笔者曾经开发过这样的页面组件,当时也是使用 JavaScript 和基础 HTML 标签类开发的。用了两个工作日才完成这样的页面组件。如果使用 Struts2 的话,就可以不需要浪费这么多时间仅仅完成一个页面组件,而忽略了业务逻辑功能的开发。
在本示例中,笔者也是在 Action 中新建了两个材料数据集合。这两个集合的元素都是字符串类型的。将这两个集合放置在 request 中,然后在 JSP 中配合 OGNL 来实现该标签。
因为该标签在页面上显示是分成左右两部分,笔者先介绍设置左边选择列表的属性。其中 leftTitle 属性是指定左边列表标题。其中 list 属性是指定左边列表中被选择数据集合,以 map 或 list 类型显示。如果是 map 类型,则 key 和 value 可以显示指定为左边列表中每个元素的值。集合中数据就是左边列表中的内容。 headerKey 和 headerValue 属性是表明左边列表缺省显示的值和内容。 listKey 和 listValue 属性则和 checkboxlist 标签中相同,都是表明左边列表值和在页面上显示的内容。它还有一个 multiple 属性表明左边列表中内容是否可以多选即同时选中左边列表中多项元素。 allowUpDownOnLeft 属性是指定 左边列表中各个元素是否可以上下移动,如果值为“ true ”就表明可以上下移动,反之则否。 emptyOption 属性是指定 左边列表中是否有空元素出现即没有任何文字的选项。如果值为“ true ”就表明有空元素出现,反之则否。
rightTitle 属性是指定右边列表标题。其中 doubleList 属性是指定右边列表中被选择数据集合,以 map 或 list 类型显示。如果是 map 类型,则 key 和 value 可以显示指定为右边列表中每个元素的值。集合中数据就是右边列表中的内容。 doubleHeaderKey 和 doubleHeaderValue 属性是表明右边列表缺省显示的值和内容。 doubleListKey 和 doubleListValue 属性则和前面段落中 listKey 和 listValue 属性相同,只不过是表明右边列表值和在页面上显示的内容。它还有一个 doubleMultiple 属性表明右边列表中内容是否可以多选即同时选中右边列表中多项元素。 allowUpDownOnRight 属性是指定 右边列表中各个元素是否可以上下移动,如果值为“ true ”就表明可以上下移动,反之则否。 doubleEmptyOption 属性是指定 右边列表中是否有空元素出现即没有任何文字的选项。如果值为“ true ”就表明有空元素出现,反之则否。
( 5 ) updownselect 标签的功能是显示选项可以上下移动的选择列表框。它的 list 属性也是指定选择列表的选择项数据集合。 moveUpLabel 属性是显示上移按钮。 moveDownLabel 属性是显示下移按钮。 selectAllLabel 属性是显示全选按钮,用来全部选择列表中的选择项。上述三个属性可以定义为自己想显示在页面上的按钮文字内容。如果不显式定义它们,则上移、下移、全选按钮文字内容默认显示为“∨”、“∧”、“*”。
该标签还有三个属性,它们是 allowMoveUp 、 allowMoveDown 、 allowSelectAll 。默认都为“ true ”,因此除非不想让选择列表中的选项被上移、下移和全选,可以显式定义他们为“ false ”,否则是不会显式定义它们的。
注意:在使用该标签时候,该标签一定要包含在 form 表单中,否则功能不会实现。