在具有多个输入的复合组件上进行验证

时间:2016-08-04 21:43:19

标签: jsf-2

我正在使用一个使用下拉列表和输入的复合组件。必填属性在下拉列表中设置,但如果'其他'如果选中,则还需要输入。我想在' cc.attr.value'上验证了必填字段,但我还需要验证' cc.attr.otherValue'。所以,我使用postValidate来检查这个必需的值。单击“保存”应验证组件内的输入,然后调用postValidate操作。但是,在postValidate之后,它仍然在更新模型阶段调用setter。

<composite:interface componentType="myInputComponent">
    <composite:attribute name="value" required="true" type="java.lang.String" />
    <composite:attribute name="otherValue" required="true" type="java.lang.String" />
</composite:interface>

<composite:implementation>
    <s:validateAll>
        <s:span id="input">
            <h:selectOneMenu id="selectInput" value="#{cc.attrs.value}" 
                required="#{cc.required}" 
                onchange="otherInput = #{rich:element('otherInput')}; otherInput.value = ''; if (this.options[this.selectedIndex].text == 'Other') { otherInput.style.display = ''; otherInput.required = #{cc.required}; } else { otherInput.style.display = 'none'; otherInput.required = false; }">
                <f:event type="postValidate" listener="#{cc.postValidate}" />

            <!-- validators here -->
            </h:selectOneMenu>

            <s:span id="other">
                <h:inputText id="otherInput" value="#{cc.attrs.otherValue}"
                    size="#{cc.attrs.width}" style="#{showOther ? '' : 'display: none'}"
                    onkeydown="#{not cc.attrs.inplace ? 'ignoreEnter(event)' : ''}"
                    onkeypress="#{cc.attrs.inplace ? 'saveOnEnter(event)' : ''}">
                    <f:event type="postValidate" listener="#{cc.postValidate}" />
                </h:inputText>
            </s:span>
        </s:span>

        <a4j:commandButton action="#{cc.attrs.saveAction}"
            value="Save" 
            execute="input"
            render="input" />

    </s:validateAll>
</composite:implementation>

这是UIComponent

@FacesComponent("myInputComponent")
public class MyInputComponent extends UIInput implements NamingContainer {

    static final String OTHER_INPUT_ID = "otherInput";
    static final String OTHER_LABEL = "Other";

    public void postValidate(ComponentSystemEvent event) {

        UIInput input = (UIInput) event.getComponent();

        if (input != null && OTHER_INPUT_ID.equals(input.getId())) {
            UIInput selectInput = (UIInput) event.getComponent().findComponent("selectInput");;
            boolean useOtherValue = false;

            if (selectInput != null) {
                Object value = selectInput.getValue();
                useOtherValue = isUseOtherValue(value);

                if (useOtherValue && isRequired()) {
                    String otherValue = (String) input.getValue();

                    if (StringUtils.emptyString(otherValue)) {
                        setInvalid(input);
                        showRequiredMessage(input);
                    }
                }
            }
        }
    }

    private void setInvalid(UIInput input) {
        input.setValid(false);
        FacesContext.getCurrentInstance().validationFailed();
    }
}

正在使用的组件:

<my:myInput value="#{bean.value}" otherValue="#{bean.otherValue}" />

在postValidate失败后仍然会调用bean.value上的setter。

我已经在只有一个输入的类似组件上尝试过此操作,当需要的值失败时,它会按预期工作。它不会进入制定者。

0 个答案:

没有答案