WebWork 2 : TutorialLesson04-01-01
This page last changed on Sep 16, 2004 by vitorsouza.
4.1.1: WebWork的UI标签在WebWork中, UI标签包装了HTML控件以便与核心框架紧密集成. 这些标签设计目标是最小化代码中的逻辑部分, 并用一个模版系统代理最终的HTML绘制. UI标签试图覆盖最普遍的情景(scenario), 并提供了一个component标签以创建定制组件.UI标签还内建支持显示内嵌的错误信息.本节解释如何利用UI标签的优点构建表单和其他图形控件, 并通过讲解模版系统的工作原理, 学习如何修改已有组件的外观以及定制新组件. 构建表单(form):WebWork提供现成的用于构建表单的标签. 其中一些标签的名字可以和HTML标签名字直接联系起来, 通过名字你就可以领会它的用途: <ww:checkbox />, <ww:file />, <ww:form />, <ww:hidden />, <ww:label />, <ww:password />, <ww:radio />, <ww:select />, <ww:submit />, <ww:textarea />和<ww:textfield />. 要使用这些标签构建表单, 只需把它们像HTML标签那样放在页面上. 唯一的区别是参数应当用双引号和单引号廓起来(key="'value'"). 这是因为非单引号的名称将使用值栈重新赋值.然我们看看这个例子: ex01-index.jsp:<%@ taglib uri="webwork" prefix="ww" %> <html> <head> <title>WebWork Tutorial - Lesson 4.1.1 - Example 1</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <style type="text/css"> .errorMessage { color: red; } </style> </head> <body> <p>UI Form Tags Example:</p> <ww:form action="'formProcessing.action'" method="'post'"> <ww:checkbox name="'checkbox'" label="'A checkbox'" fieldValue="'checkbox_value'" /> <ww:file name="'file'" label="'A file field'" /> <ww:hidden name="'hidden'" value="'hidden_value'" /> <ww:label label="'A label'" /> <ww:password name="'password'" label="'A password field'" /> <ww:radio name="'radio'" label="'Radio buttons'" list="{'One', 'Two', 'Three'}" /> <ww:select name="'select'" label="'A select list'" list="{'One', 'Two', 'Three'}" emptyOption="true" /> <ww:textarea name="'textarea'" label="'A text area'" rows="'3'" cols="'40'" /> <ww:textfield name="'textfield'" label="'A text field'" /> <ww:submit value="'Send Form'" /> </ww:form> </body> </html> ex01-index.jsp处理后的HTML结果如下:<html> <head> <title>WebWork Tutorial - Lesson 4.1.1 - Example 1</title> <style type="text/css"> .errorMessage { color: red; } </style> </head> <body> <p>UI Form Tags Example:</p> <table> <form action="formProcessing.action" method="post" > <tr> <td valign="top" colspan="2"> <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr><td valign="top"> <input type="checkbox" name="checkbox" value="checkbox_value" /> </td> <td width="100%" valign="top"> <span class="checkboxLabel"> A checkbox </span> </td> </tr> </table> </td> </tr> <tr> <td align="right" valign="top"> <span class="label"> A file field: </span> </td> <td> <input type="file" name="file" /> </td> </tr> <input type="hidden" name="hidden" value="hidden_value" /> <tr> <td align="right" valign="top"> <span class="label"> A label: </span> </td> <td> <label> </label> </td> </tr> <tr> <td align="right" valign="top"> <span class="label"> A password field: </span> </td> <td> <input type="password" name="password" /> </td> </tr> <tr> <td align="right" valign="top"> <span class="label"> Radio buttons: </span> </td> <td> <input type="radio" name="radio" id="radioOne" value="One" /> <label for="radioOne">One</label> <input type="radio" name="radio" id="radioTwo" value="Two" /> <label for="radioTwo">Two</label> <input type="radio" name="radio" id="radioThree" value="Three" /> <label for="radioThree">Three</label> </td> </tr> <tr> <td align="right" valign="top"> <span class="label"> A select list: </span> </td> <td> <select name="select" > <option value=""></option> <option value="One" >One</option> <option value="Two" >Two</option> <option value="Three" >Three</option> </select> </td> </tr> <tr> <td align="right" valign="top"> <span class="label"> A text area: </span> </td> <td> <textarea name="textarea" cols="40" rows="3" ></textarea> </td> </tr> <tr> <td align="right" valign="top"> <span class="label"> A text field: </span> </td> <td> <input type="text" name="textfield" /> </td> </tr> <tr> <td colspan="2"><div align="right" ><input type="submit" value="Send Form" /></div> </td> </tr> </form> </table> </body> </html> xwork.xml:<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.0.dtd"> <xwork> <!-- Include webwork defaults (from WebWork JAR). --> <include file="webwork-default.xml" /> <!-- Configuration for the default package. --> <package name="default" extends="webwork-default"> <action name="formProcessing" class="lesson04_01_01.FormProcessingAction"> <result name="input" type="dispatcher">ex01-index.jsp</result> <result name="success" type="dispatcher">ex01-success.jsp</result> <interceptor-ref name="validationWorkflowStack" /> </action> </package> </xwork> FormProcessingAction.java:package lesson04_01_01; import com.opensymphony.xwork.ActionSupport; public class FormProcessingAction extends ActionSupport { private String checkbox; private String file; private String hidden; private String password; private String radio; private String select; private String textarea; private String textfield; public String getCheckbox() { return checkbox; } public String getFile() { return file; } public String getHidden() { return hidden; } public String getPassword() { return password; } public String getRadio() { return radio; } public String getSelect() { return select; } public String getTextarea() { return textarea; } public String getTextfield() { return textfield; } public void setCheckbox(String checkbox) { this.checkbox = checkbox; } public void setFile(String file) { this.file = file; } public void setHidden(String hidden) { this.hidden = hidden; } public void setPassword(String password) { this.password = password; } public void setRadio(String radio) { this.radio = radio; } public void setSelect(String select) { this.select = select; } public void setTextarea(String textarea) { this.textarea = textarea; } public void setTextfield(String textfield) { this.textfield = textfield; } public String execute() throws Exception { return SUCCESS; } } FormProcessingAction-validation.xml:<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.dtd"> <validators> <field name="checkbox"> <field-validator type="requiredstring"> <message>Please, check the checkbox.</message> </field-validator> </field> <field name="file"> <field-validator type="requiredstring"> <message>Please select a file.</message> </field-validator> </field> <field name="password"> <field-validator type="requiredstring"> <message>Please type something in the password field.</message> </field-validator> </field> <field name="radio"> <field-validator type="requiredstring"> <message>Please select a radio button.</message> </field-validator> </field> <field name="select"> <field-validator type="requiredstring"> <message>Please select an option from the list.</message> </field-validator> </field> <field name="textarea"> <field-validator type="requiredstring"> <message>Please type something in the text area.</message> </field-validator> </field> <field name="textfield"> <field-validator type="requiredstring"> <message>Please type something in the text field.</message> </field-validator> </field> </validators> ex01-success.jsp:<%@ taglib uri="webwork" prefix="ww" %> <html> <head> <title>WebWork Tutorial - Lesson 4.1.1 - Example 1</title> </head> <body> <p>UI Form Tags Example result:</p> <ul> <li>checkbox: <ww:property value="checkbox" /></li> <li>file: <ww:property value="file" /></li> <li>hidden: <ww:property value="hidden" /></li> <li>password: <ww:property value="password" /></li> <li>radio: <ww:property value="radio" /></li> <li>select: <ww:property value="select" /></li> <li>textarea: <ww:property value="textarea" /></li> <li>textfield: <ww:property value="textfield" /></li> </ul> </body> </html> 另外需要注意的是在活动配置中对validationWorkflowStack的引用. 它要求WebWork按照于活动类位于统一位置的配置文件校验发送到活动中的数据, 本例中是FormProcessingAction-validation.xml (参见校验). 如果某些数据不正确, 这将不执行活动并将请求转发到输入页面, 同时将错误信息附加在每一字段上(使用方法addFieldError(String fieldName, String errorMessage)). 但是我们现在不必关心校验框架如何工作. 运行该例子并试着让某些字段空着. 你会看到UI标签显示出与校验框架集成的错误信息, 而这也是我们要向你演示的. 分离关注点能够帮助程序员和设计人员更关注自己的那部分工作.进一步阅读: UI标签 试试这个例子! 其他UI控件:除了HTML设计人员已经熟悉的标准表单控件外, WebWork还提供了其他一些空间并且也能创建定制组件. 让我们看一看WebWork提供的这些控件:
进一步阅读: UI Tags 模版系统:WebWork使用Velocity模版系统为每个UI标签绘制最终的HTML. 所有模版的缺省实现已经包含在核心发行包中并允许用户'打破常规'使用UI标签. 模版可以分别修改或整个替换以便完全定制HTML输出结果. 另外, 每一个标签都可以选择覆盖缺省模版从而允许进行精细的控制. 缺省模版位于文件webwork-2.1.1.jar的/template/xhtml目录下.如果你解开webwork-2.1.1.jar并查看目录/template/xhtml就会发现一组velocity模版文件. 大部分与某一UI标签相对应, 名称也与标签相同. 如果你已经熟悉了Velocity, 推荐你分析这些模版文件看看你能对他们做什么. 从2.1版本开始, 还有一个目录/template/simple, 这里有一个HTML表单控件的更简单版本(仅包含控件, 没有表格和文本标签). 如果你想用不同于WebWork自带的布局显示你的UI组件, 你可以:
进一步阅读: 模版, 主题 下面的例子中演示了第三种方式. 需要注意的是, 缺省情况下, 指定的主题目录应当位于/template目录下, 指定的模版文件应当位于/template/xhtml目录下. ex02.jsp:<%@ taglib uri="webwork" prefix="ww" %> <html> <head> <title>WebWork Tutorial - Lesson 4.1.1 - Example 2</title> </head> <body> <p>Template Change Example:</p> <p><ww:checkbox name="'checkbox'" label="'A checkbox'" fieldValue="'checkbox_value'" theme="'mytheme'" /></p> <p><ww:textfield name="'textfield'" label="'A text field'" template="mytextfield.vm" /></p> </body> </html> /template/mytheme/checkbox.vm:<div align="center"> <input type="checkbox" name="$!webwork.htmlEncode($parameters.name)" value="$!webwork.htmlEncode($parameters.fieldValue)" #if ($parameters.nameValue) checked="checked" #end #if ($parameters.disabled == true) disabled="disabled" #end #if ($parameters.tabindex) tabindex="$!webwork.htmlEncode($parameters.tabindex)" #end #if ($parameters.onchange) onchange="$!webwork.htmlEncode($parameters.onchange)" #end #if ($parameters.id) id="$!webwork.htmlEncode($parameters.id)" #end /><br /> $!webwork.htmlEncode($parameters.label) </div> /template/xhtml/mytextfield.vm:<div align="center"> <input type="text" name="$!webwork.htmlEncode($parameters.name)" #if ($parameters.size) size="$!webwork.htmlEncode($parameters.size)" #end #if ($parameters.maxlength) maxlength="$!webwork.htmlEncode($parameters.maxlength)" #end #if ($parameters.nameValue) value="$!webwork.htmlEncode($parameters.nameValue)" #end #if ($parameters.disabled == true) disabled="disabled" #end #if ($parameters.readonly) readonly="readonly" #end #if ($parameters.onkeyup) onkeyup="$!webwork.htmlEncode($parameters.onkeyup)" #end #if ($parameters.tabindex) tabindex="$!webwork.htmlEncode($parameters.tabindex)" #end #if ($parameters.onchange) onchange="$!webwork.htmlEncode($parameters.onchange)" #end #if ($parameters.id) id="$!webwork.htmlEncode($parameters.id)" #end /><br /> $!webwork.htmlEncode($parameters.label) </div> ex02.jsp处理的HTML结果:<html> <head> <title>WebWork Tutorial - Lesson 4.1.1 - Example 2</title> </head> <body> <p>Template Change Example:</p> <p><div align="center"> <input type="checkbox" name="checkbox" value="checkbox_value" /><br /> A checkbox </div></p> <p><div align="center"> <input type="text" name="textfield" /><br /> A text field </div></p> </body> </html> 试试这个例子! 构建定制的UI组件:有时候没有一个WebWork附带的UI组件能够满足你的要求. 这时, 推荐的方式就是创建自己的定制组件. 通过这种方式, 保持了页面了清晰且与布局和错误检查问题无关, 并促进了组件复用.要创建一个定制组件, 只需要为它创建一个Velocity模版, 就像那些已有组件那样. 为把它用在页面上, 使用<ww:component />标签并在template参数中指定模版即可. 要传递模版所需的参数, 可以使用<ww:param />标签(参见4.1). 下面的例子演示了一个定制的日期字段的创建过程.进一步阅读: UI标签 ex03.jsp:<%@ taglib uri="webwork" prefix="ww" %> <html> <head> <title>WebWork Tutorial - Lesson 4.1.1 - Example 3</title> </head> <body> <p>Custom Component Example:</p> <p> <ww:component template="datefield.vm"> <ww:param name="'label'" value="'Date'" /> <ww:param name="'name'" value="'mydatefield'" /> <ww:param name="'size'" value="3" /> </ww:component> </p> </body> </html> /template/xhtml/datefield.vm:#set ($name = $parameters.get('name')) #set ($size = $parameters.get('size')) #set ($yearSize = $size * 2) $parameters.get('label'): <input type="text" name="${name}.day" size="$size" /> / <input type="text" name="${name}.month" size="$size" /> / <input type="text" name="${name}.year" size="$yearSize" /> (dd/mm/yyyy) ex03.jsp处理的HTML结果:<html> <head> <title>WebWork Tutorial - Lesson 4.1.1 - Example 3</title> </head> <body> <p>Custom Component Example:</p> <p> Date: <input type="text" name="mydatefield.day" size="3" /> / <input type="text" name="mydatefield.month" size="3" /> / <input type="text" name="mydatefield.year" size="6" /> (dd/mm/yyyy) </p> </body> </html> 试试这个例子! 上一课 | 下一课 |
Document generated by Confluence on Dec 14, 2004 16:36 |