Любой способ обойти проверки и все еще обновить значения бина? - PullRequest
1 голос
/ 11 апреля 2011

Я использую Richfaces. Я сталкиваюсь с ситуацией, когда у меня есть форма и 2 кнопки. При нажатии на одну из кнопок, скажем button1, мне нужны проверки. На нажатие другого, button2, я не. Проблема возникает, когда я нажимаю на кнопку1 и получаю все сообщения об ошибках проверки. Это предотвращает нажатие кнопки 2. Я попытался ajaxSingle, немедленный, который помогает в обход проверки, но значения bean не обновляются Как мне этого добиться?

Код:

<h:inputSecret value="#{bean.value} redisplay="true"/>
<a4j:commandButton immediate="true" actionListener="#{bean.actionListener} reRender="ID_OF_PANEL_SURROUNDING_THIS_CODE"/>

Боб: w

public class bean {
.
.
.
public void actionListener(ActionEvent e) {
value = "New value";
}
.
.
.
}

Ответы [ 2 ]

1 голос
/ 11 апреля 2011

Что на самом деле можно сделать для такого случая - это написать собственный валидатор и выполнить в нем соответствующие проверки.

conditionalValidation.xhtml:

Обратите внимание на h:inputHidden, объединяющий идентификаторыи вызвать пользовательский валидатор для вызова.

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:c="http://java.sun.com/jstl/core"
    xmlns:a4j="http://richfaces.org/a4j"
    xmlns:rich="http://richfaces.org/rich"  
    template="/WEB-INF/template/default.xhtml">

    <ui:param name="title" value="Conditional Validation"/>
    <ui:param name="bean" value="#{conditionalValidationBean}"/>

    <ui:define name="content">
        <a4j:form id="frmConditionalValidation">
            <h:panelGrid columns="2">
                <h:outputLabel for="txtValue1" value="Value 1"/>
                <h:panelGroup>
                    <h:inputText id="txtValue1" value="#{bean.value1}"/>
                    <h:message for="txtValue1"/>
                </h:panelGroup>
                <h:outputLabel for="txtValue2" value="Value 2"/>
                <h:panelGroup>
                    <h:inputText id="txtValue2" value="#{bean.value2}"/>
                    <h:message for="txtValue2"/>
                </h:panelGroup>
            </h:panelGrid>
            <h:inputHidden id="inpDetailsProvider" required="true"
                validator="#{bean.conditionalValidator}" value="1">
                <f:attribute name="forceValidationBtnId" value="btnForceValidation"/>
                <f:attribute name="value1InputId" value="txtValue1"/>
                <f:attribute name="value2InputId" value="txtValue2"/>
            </h:inputHidden>
            <h:commandButton id="btnForceValidation" value="Force Validation"/>
            <h:commandButton id="btnByPassValidation" value="Bypass Validation"/>
        </a4j:form>
    </ui:define>
</ui:composition>

ConditionalValidationBean.java

public class ConditionalValidationBean {

    private String value1;
    private String value2;

    @SuppressWarnings("unused")
    public void conditionalValidator(FacesContext context, UIComponent component, Object value) {
        String forceValidationBtnId = (String) component.getAttributes().get("forceValidationBtnId");
        String value1InputId = (String) component.getAttributes().get("value1InputId");
        String value2InputId = (String) component.getAttributes().get("value2InputId");

        UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
        UICommand forceValidationBtn = findComponent(viewRoot, forceValidationBtnId, UICommand.class);

        Map<String, String> params = context.getExternalContext().getRequestParameterMap();
        boolean forceValidation = params.containsKey(forceValidationBtn.getClientId(context)); 

        if(forceValidation) {
            UIInput value1Input = findComponent(viewRoot, value1InputId, UIInput.class);
            UIInput value2Input = findComponent(viewRoot, value2InputId, UIInput.class);

            String v1 = (String) value1Input.getValue();
            if(v1 == null || v1.trim() == "") {
                value1Input.setValid(false);
                FacesMessage valueRequiredMsg = new FacesMessage("Value required");
                context.addMessage(value1Input.getClientId(context), valueRequiredMsg);
            }

            // Rest of validation logic.
        }
    }

    public static <T> T findComponent(UIComponent base, String id, Class<T> returnType) {
        if (id.equals(base.getId())) {
            return returnType.cast(base);
        }

        Iterator<UIComponent> children = base.getFacetsAndChildren();

        while (children.hasNext()) {
            T found = findComponent(children.next(), id, returnType);

            if (found != null) {
                return returnType.cast(found);
            }
        }

        return null;
    }    

    public String getValue1() {
        return value1;
    }

    public String getValue2() {
        return value2;
    }

    public void setValue1(String value1) {
        this.value1 = value1;
    }

    public void setValue2(String value2) {
        this.value2 = value2;
    }

}
1 голос
/ 11 апреля 2011

Установите немедленный атрибут в true во второй кнопке.

Немедленный атрибут пропускает проверку ваших значений, но используя немедленный для чего-либо, кроме тривиального случая кнопки отмены , проблематично.Если ваша button2 является какой-то кнопкой отмены, проблем нет.

Если вам нужно реализовать что-то более сложное, чем кнопка отмены, есть некоторые решения этих проблем * 1018.* которую вы можете найти в статье ниже.

How_The_Immediate_Attribute_Works

...