【问题标题】:Validate if list in <ui:repeat><h:inputText> has at least one non-empty/null value验证 <ui:repeat><h:inputText> 中的列表是否至少有一个非空/空值
【发布时间】:2015-01-19 14:15:12
【问题描述】:

我的模型中有一个List&lt;String&gt;

private List<String> list;

// Add to list: "d","e","f","a","u","l","t"
// Getter.

我将其呈现在如下视图中:

<ui:repeat value="#{bean.list}" varStatus="loop">
    <h:inputText value="#{bean.list[loop.index]}"/>
</ui:repeat>

这很好用。现在我想验证列表是否包含至少一个非空/空项目。如何为此创建自定义验证器?

【问题讨论】:

    标签: list jsf validation uirepeat


    【解决方案1】:

    使用自定义验证器很难做到这一点。也就是说,物理上只有一个输入组件的状态随着每一轮迭代而变化。最好的办法是挂上&lt;ui:repeat&gt;postValidate 事件,然后在UIRepeat 上通过UIComponent#visitTree() 访问它的孩子。

    这是一个启动示例:

    <ui:repeat value="#{bean.list}" varStatus="loop">
        <f:event type="postValidate" listener="#{bean.validateOneOrMore}" />
        <h:inputText value="#{bean.list[loop.index]}"/>
    </ui:repeat>
    

    使用这个validateOneOrMore() 方法(同样,这只是一个启动示例,这种方法天真地假设转发器中只有一个UIInput 组件):

    public void validateOneOrMore(ComponentSystemEvent event) {
        final FacesContext context = FacesContext.getCurrentInstance();
        final List<String> values = new ArrayList<>();
    
        event.getComponent().visitTree(VisitContext.createVisitContext(context), new VisitCallback() {
            @Override
            public VisitResult visit(VisitContext context, UIComponent target) {
                if (target instanceof UIInput) {
                    values.add((String) ((UIInput) target).getValue());
                }
                return VisitResult.ACCEPT;
            }
        });
    
        values.removeAll(Arrays.asList(null, ""));
    
        if (values.isEmpty()) {
            event.getComponent().visitTree(VisitContext.createVisitContext(context), new VisitCallback() {
                @Override
                public VisitResult visit(VisitContext context, UIComponent target) {
                    if (target instanceof UIInput) {
                        ((UIInput) target).setValid(false);
                    }
                    return VisitResult.ACCEPT;
                }
            });
    
            context.validationFailed();
            context.addMessage(null, new FacesMessage("Please fill out at least one!"));
        }
    }
    

    注意它访问了树两次;第一次收集值,第二次将这些输入标记为无效。

    OmniFaces 有一个 &lt;o:validateOneOrMore&gt; 组件,它在固定组件上做类似的事情,但它不是为在动态重复组件中使用而设计的。

    另见:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-13
      相关资源
      最近更新 更多