Mik*_*keR 6 validation el jsf-2 uirepeat
我正在寻找一些关于我遇到的问题的指导.
我想要完成的是通过验证和所有内容动态构建页面.最终结果是允许用户通过管理功能配置页面上的字段.下面是我用作测试页面的代码的副本,我在其中循环"已配置"字段并使用定义的标准写出字段.
<ui:repeat var="field" value="#{eventMgmt.eventFields}" varStatus="status">
<div class="formLabel">
<h:outputLabel value="#{field.customName}:"></h:outputLabel>
</div>
<div class="formInput">
<h:inputText id="inputField" style="width:# {field.fieldSize gt 0 ? field.fieldSize : 140}px;">
<f:validateRegex disabled="#{empty field.validationPattern}" pattern="#{field.validationPattern}"></f:validateRegex>
</h:inputText>
<h:message for="inputField" showDetail="true" errorClass="errorText"></h:message>
</div>
</ui:repeat>
Run Code Online (Sandbox Code Playgroud)
在页面呈现并且我尝试提交字段的任何值之后,我收到以下消息"正则表达式模式必须设置为非空值".这显然意味着表达式没有填充.让我感兴趣的是,在评估EL时,将禁用没有表达式的字段.我也可以使用相同的代码#{field.validationPattern}并将其放在页面中,并在页面上写入正确的值.
所以,我的问题是:1.这可能吗?2. JSF容器在什么时候看看绑定Pattern for validate regex?3.我做错了什么或者这样做的正确方法是什么?
我正在运行Tomcat 7.0.22,Mojarra 2.1.5和Eclipse作为我的IDE.
Bal*_*usC 13
这是因为使用<f:validateRegex>其属性取决于当前迭代的项目<ui:repeat>.
该<f:xxx>标签是标签处理器,而不是UI组件.在视图构建期间构建UI组件树时,将解析和评估标记处理程序.在视图构建期间评估所有EL.该<h:xxx>标签和一些<ui:xxx>类似的标签<ui:repeat>是UI组件.在视图渲染时间内评估它们的所有EL.
因此,在您的情况下,当<f:validateRegex>解析并执行时,它#{field}在当前EL范围中不可用,因此评估为null.
有几种方法可以让它发挥作用.
将验证器移动到表示Field并引用它的类,如下所示:
<h:inputText ... validator="#{field.validate}" />
Run Code Online (Sandbox Code Playgroud)
在Field类中,您手动实例化它:
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
if (pattern != null) {
RegexValidator regexValidator = new RegexValidator();
regexValidator.setPattern(pattern);
regexValidator.validate(context, component, value);
}
}
Run Code Online (Sandbox Code Playgroud)
或者,将#{eventMgmt.eventFields}a 包装ListDataModel<Field>并将验证器绑定到#{eventMgmt}bean.这样您就可以根据行数据设置验证器的属性:
<h:inputText ... validator="#{eventMgmt.validate}" />
Run Code Online (Sandbox Code Playgroud)
在后面的bean类后面#{eventMgmt}:
private DataModel<Field> model;
private RegexValidator regexValidator;
@PostConstruct
public void init() {
regexValidator = new RegexValidator();
}
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
String pattern = model.getRowData().getPattern();
if (pattern != null) {
regexValidator.setPattern(pattern);
regexValidator.validate(context, component, value);
}
}
Run Code Online (Sandbox Code Playgroud)
或者,创建一个自定义Validator,它将RegexValidator模式扩展并设置为组件的自定义属性,<f:attribute>并对其进行Validator拦截.该<f:attribute>基本上增加了一个新的属性与一个未计算的成分ValueExpression,所以它会当你调用它进行重新评估.例如:
<h:inputText ...>
<f:validator validatorId="extendedRegexValidator" />
<f:attribute name="pattern" value="#{field.pattern}" />
</h:inputText>
Run Code Online (Sandbox Code Playgroud)
同
@FacesValidator("extendedRegexValidator")
public class ExtendedRegexValidator extends RegexValidator {
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
String pattern = (String) component.getAttributes().get("pattern");
if (pattern != null) {
setPattern(pattern);
super.validate(context, component, value);
}
}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您碰巧使用JSF实用程序库OmniFaces,请使用它<o:validator>.例如
<h:inputText ...>
<o:validator validatorId="javax.faces.RegularExpression" pattern="#{field.pattern}" />
</h:inputText>
Run Code Online (Sandbox Code Playgroud)
是的,就是这样.这<o:validator>将确保将所有属性评估为延迟表达式而不是立即表达式.