第一部分:源码
// Copyright 2006, 2007, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry5.corelib.components;
import org.apache.tapestry5.CSSClassConstants;
import org.apache.tapestry5.MarkupWriter;
import org.apache.tapestry5.ValidationTracker;
import org.apache.tapestry5.annotations.Environmental;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.corelib.internal.InternalMessages;
import org.apache.tapestry5.services.FormSupport;
import java.util.List;
/**
* Standard validation error presenter. Must be enclosed by a
* {@link org.apache.tapestry5.corelib.components.Form} component. If errors are present, renders a
* div element around a banner message and around an unnumbered list of
* error messages. Renders nothing if the {@link org.apache.tapestry5.ValidationTracker} shows no
* errors.
*/
public class Errors
{
/**
* The banner message displayed above the errors. The default value is "You must correct the
* following errors before
* you may continue.".
*/
@Parameter("message:default-banner")
private String banner;
/**
* The CSS class for the div element rendered by the component. The default value is "t-error".
*/
@Parameter(name = "class")
private String className = CSSClassConstants.ERROR;
// Allow null so we can generate a better error message if missing
@Environmental(false)
private ValidationTracker tracker;
void beginRender(MarkupWriter writer)
{
if (tracker == null)
throw new RuntimeException(InternalMessages.encloseErrorsInForm());
if (!tracker.getHasErrors())
return;
writer.element("div", "class", className);
// Inner div for the banner text
writer.element("div");
writer.write(banner);
writer.end();
List<String> errors = tracker.getErrors();
if (!errors.isEmpty())
{
// Only write out the <UL> if it will contain <LI> elements. An empty <UL> is not
// valid XHTML.
writer.element("ul");
for (String message : errors)
{
writer.element("li");
writer.write(message);
writer.end();
}
writer.end(); // ul
}
writer.end(); // div
}
}
第二部分:简介
<t:errors>主要用于在非客户端验证情况下的form错误信息显示。既然是非客户端验证情况下,就需要将<t:form>组件的clientValidation属性设置成false,否则你会看不到<t:errors>产生的ul标签。
该组件有两个参数:banner(用来指定错误列表的标题信息,默认是"You must correct the following errors before you may continue.".)和class(用来指定错误列表的CSS样式class名,默认是"t-error")
第三部分:测试
以下是测试用的最终代码文件
start.tml
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<head>
<title>t:errors</title>
<style>
.error{color:black;}
</style>
</head>
<body>
<t:form clientValidation="false">
<t:label for="userName"/>
<t:textfield t:id="userName" validate="required" value="userName"/>
<t:label for="password"/>
<t:textfield t:id="password" validate="required" value="password"/>
<input type="submit" value="Search"/>
<t:errors/>
<t:errors banner="literal:指定banner,未指定class"/>
<t:errors banner="literal:同时指定banner和class" class="literal:error"/>
</t:form>
</body>
</html>
Start.java
package jumpstart.web.pages;
import org.apache.tapestry5.annotations.Property;
public class Start {
@Property
private String userName;
@Property
private String password;
}
最终的效果
最终效果(HTML)
<form action="/jumpstart/start.form" method="post" id="form"><div class="t-invisible"><input value="BUFCDsKEovSgBAAA=" name="t:formdata" type="hidden"></input></div>
<label class="t-error" for="userName">User Name</label>
<input class="t-error" value="" id="userName" name="userName" type="text"></input><img id="userName_icon" class="t-error-icon" alt="" src="/jumpstart/assets/de7155d829bf8977/core/spacer.gif"/>
<label class="t-error" for="password">Password</label>
<input class="t-error" value="" id="password" name="password" type="text"></input><img id="password_icon" class="t-error-icon" alt="" src="/jumpstart/assets/de7155d829bf8977/core/spacer.gif"/>
<input value="Search" type="submit"></input>
<div class="t-error"><div>在你继续之前,必须纠正如下错误.</div><ul><li>请输入User Name的内容。</li><li>请输入Password的内容。</li></ul></div>
<div class="t-error"><div>指定banner,未指定class</div><ul><li>请输入User Name的内容。</li><li>请输入Password的内容。</li></ul></div>
<div class="error"><div>同时指定banner和class</div><ul><li>请输入User Name的内容。</li><li>请输入Password的内容。</li></ul></div>
</form>
第四部分:分析
源码中banner的参数指定的默认值使用了国际化message绑定表达式前缀,default-banner的值可以直接在组件所在包下的properties下找到。
源码中class的参数指定的默认值是CSSClassConstants.ERROR(常量值"t-error")使用属性className保存,class只是指定的一个使用的别名。
源码中的beginRender方法主要知道tracker.getHasErrors()和tracker.getErrors()两句的作用就好了。
整个beginRender方法最后writer出来的结果就像上面图中所诠释的。
<div class="t-error">
<div>指定banner,未指定class</div>
<ul>
<li>请输入User Name的内容。</li>
<li>请输入Password的内容。</li>
</ul>
</div>
根据这样的效果代码去理解源码就很好理解了。