JSF 2.0;验证程序标记“已禁用”取决于页面的值

时间:2012-03-28 10:56:10

标签: validation jsf jsf-2

在我的jsf应用程序中,我想验证一个只应该验证的字段,当选中SelectOneRadio中的一个选项时。

我发现,<f:validator>有一个名为“禁用”的属性。

我可以使用它来检查其他字段的值吗?

我试过,但我无法访问我的bean的值。

<h:selectOneRadio value="#{myBean.checkedSelectOneRadioValue}">
    <f:selectItems value="#{myBean.valuesForSelectOneRadio}" />
</h:selectOneRadio>


<f:validator validatorId="myValidator" disabled="#{myBean.checkedSelectOneRadioValue == 'TEST'}" />

有没有办法在没有编写自己的validatorhandler的情况下达到目标?

谢谢!

3 个答案:

答案 0 :(得分:9)

<f:validator>是标记处理程序,而不是UI组件。它的所有属性都是在视图构建时评估的每个定义,而不是在视图渲染时。视图构建时间是将XHTML文件解析为context.getViewRoot()可用的JSF组件树的那一刻。通过在(ajax)操作中返回null / void,通常会在回发中将相同的视图重用到同一视图。

因此,您不能让标记处理程序属性依赖于在回发请求期间可以更改的呈现时间属性。其中一种方法是在自定义验证器本身内执行该检查。

E.g。

<h:inputText>
    <f:validator validatorId="myValidator" />
    <f:attribute name="radio" value="#{myBean.checkedSelectOneRadioValue}" />
</h:inputText>

@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {     
    if (!"TEST".equals(component.getAttributes().get("radio"))) {
        return;
    }

    // Perform actual validation here.
}

您也可以使用OmniFaces <o:validator>代替。它扩展了标准<f:validator>,并在属性中基于请求评估EL。

<h:inputText>
    <o:validator validatorId="myValidator" disabled="#{bean.checkedSelectOneRadioValue == 'TEST'}" />
</h:inputText>

另请参阅下面发布相关摘录的showcase examplesource code

@Override
public void apply(FaceletContext context, UIComponent parent) throws IOException {
    if (!ComponentHandler.isNew(parent)) {
        return;
    }

    final javax.faces.validator.Validator validator = createValidator(context);
    final RenderTimeAttributes attributes = collectRenderTimeAttributes(context, validator);
    final ValueExpression disabled = getValueExpression(context, "disabled", Boolean.class);
    ((EditableValueHolder) parent).addValidator(new javax.faces.validator.Validator() {

        @Override
        public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
            if (disabled == null || Boolean.FALSE.equals(disabled.getValue(context.getELContext()))) {
                attributes.invokeSetters(context.getELContext(), validator);
                validator.validate(context, component, value);
            }
        }
    });
}

答案 1 :(得分:0)

使用JSF 2.0,您可以使用f:ajax进行部分提交。将此标记添加到h:selectOneRadio

<h:selectOneRadio value="#{myBean.checkedSelectOneRadioValue}">
    <f:ajax render="idOfInputText"/>
    <f:selectItems value="#{myBean.valuesForSelectOneRadio}" />
</h:selectOneRadio>
...
<h:inputText id="idOfInputText">
    <f:validator validatorId="myValidator" 
                 disabled="#{myBean.checkedSelectOneRadioValue eq 'TEST'}" />
</h:inputText>

使用验证程序将render属性内容替换为输入字段的实际ID。这假设selectOneRadio和inputText在同一个NamingContainer中。

答案 2 :(得分:-1)

为了避免在评论中进行扩展讨论,我将提供我的建议,作为进一步讨论的答案......

起初它应该是

disabled="#{myBean.checkedSelectOneRadioValue == 'TEST'}

disabled="#{myBean.checkedSelectOneRadioValue eq 'TEST'}

另外,至少在ICEFaces中(和MyFaces也应该有这个功能),你可以使用:

<h:selectOneRadio value="#{myBean.checkedSelectOneRadioValue}" partialSubmit="true"> <f:selectItems value="#{myBean.valuesForSelectOneRadio}" /> </h:selectOneRadio>

这应该在更改selectoneradio的值后强制执行ajax请求,并且验证器禁用的检查应该能够从bean中获取它。

如果这不起作用,MyFaces中可能会有autoSubmit或类似内容......