Struts Recipes 的合着者 Danilo Gurovich 从 George Franciscus 停止的地方开始介绍了易于使用的创建动态选择复选框的 Struts 诀窍
在用户界面设计中复选框组不如它的同类 —— 多行选择框那样流行它们基本上做的是同一件事即选择映射到单一 name 属性的一组选项当在组中使用时复选框执行的功能实际与多行选择框一样但是它们占据的屏幕空间更多当希望用户在选择一个或多个选项之前能够看到所有选项的时候这会很有好处
虽然在选项不多的时候多行选择框通常提供更好的观感但是当选择框必须动态呈现而且包含预选功能时对企业应用程序来说复选框组会是更好的选择幸运的是使用 Struts 框架可以很容易地创建动态复选框组
在这篇文章中我将介绍一个简单的诀窍用 Struts 的 <html:multibox/> 和 <logic:iterate/> 标记在应用程序的视图层呈现大量条目在本例中是 Java? Server Page(JSP)
我先从使用复选框元素显示简单的 String[] 数组开始数组中包含喜玛拉雅山的顶峰高度然后我将创建另外一个 String[] 数组包含 selectedMountains 代表已经选中的复选框复选框的预选情况会在两个数组的交叉中产生如果 selectedMountains 的初始数组为空那么所有复选框最初都会显示为未选中
请参阅 下载 获得完整的示例源代码应当拥有跟随本文所需要的每样东西如果需要下载 Struts 框架请参阅 参考资料
创建动态复选框
创建动态复选框的诀窍包含三个主要部分
一个表单 bean容纳复选框的 String[] 数组和表示选中复选框的 String[] 数组
一个 JSP带有一个表单在需要的时候显示复选框
一个简单的 Action 类从表单页面转到显示页面
请注意 Himalayas 示例非常简单用来填充复选框的字段应当来自更复杂的模型比如这样的模型它能够标识用户并选择要显示的字段然后把业务对象认为需要的选项预先选中我采用简单的模型是为了更好地演示 Struts 的用户界面功能代码示例使用 JSP 脚本语言是为了表示清楚
第 步 创建表单 bean
我先从创建 Struts 表单 bean 开始它包含填充复选框所需要的信息请注意清单 中的 TestFormjava 包含了两个示例 String[] 数组变量的 getter 和 setter数组 mountains 代表示例复选框的 全部选项数组 selectedMountains 代表预选的在浏览器中显示为选中的元素
除了代表初始选中的复选框selectedMountains 还代表处理表单时由用户选中的复选框(它只代表最终选中的元素)当请求页面时会显示复选框当我在它们之间迭代时与 selectedMountains 匹配的复选框元素就是选中的元素
清单 显示了 TestFormjava 的完整代码
清单 TestFormjava
package comstrutsrecipes;
import javaxservlethttpHttpServletRequest;
import orgapachestrutsactionActionError;
import orgapachestrutsactionActionErrors;
import orgapachestrutsactionActionForm;
import orgapachestrutsactionActionMapping;
public final class CheckboxTestForm
extends ActionForm {
// Instance Variables
/*Mountains preselected*/
private String[]
selectedMountains
=
{EverestKLhotse};
/*the ten tallest Mountains to iterate through*/
private String[]
mountains
=
{EverestKKangchenjungaLhotse
MakaluKangchenjunga South
Lhotse MiddleKangchenjunga West
Lhotse SharCho Oyu};
/*Getter for selectedMountains*/
public String[] getSelectedMountains() {
return thisselectedMountains;
}
/*Setter for selectedMountains*/
public void setSelectedMountains(String[] selectedMountains) {
thisselectedMountains = selectedMountains;
}
/*Getter for the mountains*/
public String[] getMountains() {
return thismountains;
}
/*Setter for the mountains*/
public void setMountains(String[] mountains) {
thismountains = mountains;
}
}
第 步 编写 JSP 代码
接下来我要编写页面的 JSP 代码把 TestFormjava 的信息传递给视图层在编写这个代码时关键是要把对应的 Struts 标记库导入 JSP清单 的 JSP 代码表示的是一个简单的表单显示复选框中相应的框已经选中
清单 带有表单的 JSP
<%@taglib uri=html prefix=html%>
<%@taglib uri=bean prefix=bean%>
<%@taglib uri=logic prefix=logic%>
<% html code etc >
<html:form
action=/FormAction
name=testForm
type=comstrutsrecipesCheckboxTestForm>
<h><bean:message key=testForminstruction/></h>
<logic:iterate name=testForm
property=mountains
id=mountain>
<% create the checkbox and selected attribute >
<html:multibox property=selectedMountains>
<bean:write name=mountain/>
</html:multibox>
<% create the label note that br tag will format it vertically >
<bean:write name=mountain/><br/>
</logic:iterate>
<br/>
<html:submit/><html:reset/>
</html:form>
<% some more html code etc >
注意我用 Struts <bean:message/> 标记表示文本用 <html:multibox/> 表示 HTML 复选框用 <logic:iterate/> 标记在数组中迭代并创建相应内容我的表单在 JSP 中通过 <html:form/> 标记被实例化
下一步是对 <logic:iterate/> 标记中的 mountains 字段进行迭代在这么做的时候我创建了一个变量(mountain)用它来填充复选框并用 <bean:write/> 标记给它一个标签要在复选框中创建 selected 属性我要再次使用 <logic:iterate/> 和 <html:multibox/> 标记<html:multibox/> 标记中的 property 属性由 selectedMountains 字段填充当 selectedMountains 等于 mountain 时selectBox 就是选中的
第 步 编写 Action 类
最后一步是编写 Action 类清单 比起其他清单做的事并不多我做的只是得到 selectedMountains 的 String[] 数组并使它可以用于页面
清单 表单的 Action
import orgapachestrutsactionAction;
import orgapachestrutsactionActionForm;
import orgapachestrutsactionActionForward;
import orgapachestrutsactionActionMapping;
import javaxservletServletException;
import javaxservlethttpHttpServletRequest;
import javaxservlethttpHttpServletResponse;
import javaxservlethttpHttpSession;
/**
* A simple Action for Checkbox test
*
* @author Danilo Gurovich
*/
public final class CheckboxTestAction
extends Action {
// OTHER METHODS
/**
* The execute method
*
* @param mapping ActionMapping
* @param form CheckboxTestForm
* @param request HttpServletRequest
* @param response HttpServletRespons
* @return success to the confirmation page
* @throws ServletException not thrown but could be!
* @throws Exception ditto
*/
public ActionForward execute(ActionMapping mapping
ActionForm form
HttpServletRequest request
HttpServletResponse response)
throws ServletException Exception {
// Extract attributes needed
String[] selectedMountains =
((CheckboxTestForm) form)getSelectedMountains()
;
Systemoutprintln(htmlString RETURNED*\n +
selectedMountainstoString());
//Save the htmlString in the session for later
HttpSession session = requestgetSession();
sessionsetAttribute(CheckboxConstantsMOUNTAINS selectedMountains);
return (mappingfindForward(success));
}
}
扩充 Himalayas
有了这个代码工作就完成了差不多可以展示成果了!用户现在可以提交 JSP 表单并在 Action 类引用的对应页面中查看结果清单 中的代码段显示了用户在简单 JSP 页面的表单中选中的复选框列表
清单 复选框选择的结果
<%@taglib uri=html prefix=html%>
<%@taglib uri=bean prefix=bean%>
<%@taglib uri=logic prefix=logic%>
<% html code etc >
<logic:iterate id=mountain property=mountains name=testForm>
<bean:write name=mountain/><br/>
</logic:iterate>
<hr size= color=black/>
<% some more html code etc >
这个诀窍的工作方式
这个诀窍的关键是表单 bean 中的字段被传递到页面查看相关 JSP 代码有助于澄清这点一旦表单 bean 被实例化
<html:form action=/FormAction
name=testForm
type= comstrutsrecipesCheckboxTestForm>
下一步为 Java 类的 mountains 变量中的每个 mountain 创建一个复选框要做到这一点我必须像下面这样在 String[] 数组中迭代
<logic:iterate id=mountain
property=mountains
name=testForm>
使用 <logic:iterate> 标记我调用了 testForm bean 中的 getMountains() 方法它在这个数组中迭代并把每个值作为已经命名的 pageContext() 级的 String mountain[] 数组变量返回(即 id=mountain)
在这里可以看到 <html:multibox/> 标记的效果以及如何显示它
<html:multibox property=selectedMountains>
<bean:write name=mountain/>
</html:multibox>
<bean:write name=mountain/><br/>
注意 property 属性被 selectedMountains 填充这是我选中的变量当这个变量与 <html:multibox/> 值(即 multibox 标记中的 <bean:write/>)对应时在呈现表单的时候它就表现为选中如果用户选中表单或取消选中那么新的 selectedMountains 值就被发送给 Action 类进行处理这个迭代中的第二个 <bean:write/> 标记创建该标记使用的标签后面跟着 <br/> 标记让视图在一长列中显示这些标记
扩展这个诀窍
通过使用 Struts LabelValueBean 类代替简单的 String[] 数组可以对动态复选框这个诀窍进行扩展从而为复选框创建不同的标签先从添加 LabelValueBeans 到 javautilList 开始然后对列表进行迭代把 LabelValueBeans 标签和值释放到适当的位置这个略微复杂的诀窍与动态复选框诀窍的效果相同但是它的结果更适合实际的用户界面设计清单 显示了扩展的动态复选框诀窍
清单 添加标签到动态复选框
<logic:iterate id=mountainlb
property=mountainslb
name=testForm>
<bean:define id=mountainbean
name=mountainlb
type=orgapachestrutsutilLabelValueBean/>
<html:multibox property=selectedMountains>
<bean:write name=mountainbean
property=value/>
</html:multibox>
<bean:write name=mountainbean
property=label/><br/>
</logic:iterate>
注意这里大的变化是用 <bean:define/> 在迭代的时候创建 LabelValueBean然后用 <bean:write/> 输出每个 mountainbean 的属性(即 orgapachestrutsutilLabelValueBean 类的 getLabel() 和 getValue() 方法)
结束语
Struts 对于复选框的动态呈现和预选提供了优秀的支持这个诀窍是我合着 Struts Recipes 的原因 —— 那时我已经发现许多与 Struts 框架相关的理论和服务器端信息但是用户界面编程多数被忽略了或者被掩盖了在上上下下找了一圈使用 Struts 创建复选框的诀窍之后我放弃了并自己写了一个通过把不同的部分组合起来我可以创建适合我的动态复选框系统
您会注意到代码示例被设置为适合用作不同用户界面小控件和布局想法的测试温床实际上我在书中的大多数用户界面示例中都使用了它只需要调整 Action 类和我的模型去适合诀窍的需求而已我还把它用在测试不同的想法上这样就不用在我正在处理的应用程序内部花太多时间为某些东西编码了