Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mark other components invalid in a custom multi-field validator

I refer to one of BalusC's answers: JSF doesn't support cross-field validation, is there a workaround?

I follow the same way, and come out with code as below:

in .xhtml

<h:form id="form1">
  <div>
    <p:messages globalOnly="true" display="text" />

        <h:inputHidden value="true">
            <f:validator validatorId="fooValidator" />
            <f:attribute name="input1" value="#{input1}" />
            <f:attribute name="input2" value="#{input2}" />
            <f:attribute name="input3" value="#{input3}" />
        </h:inputHidden>

        <h:panelGrid columns="3">  
            <h:outputText value="name 1: " />
            <p:inputText binding="#{input1}" id="input11" value="#{testPage.input1}" />
            <p:message for="input11" display="text"/>
        </h:panelGrid>
        <h:panelGrid columns="3">
            <h:outputText value="name 2: " />               
            <p:inputText binding="#{input2}" id="input22" value="#{testPage.input2}" />
            <p:message for="input22" display="text"/>
        </h:panelGrid>
        <h:panelGrid columns="3">
            <h:outputText value="name 3: " />
            <p:inputText binding="#{input3}" id="input33" value="#{testPage.input3}" />
            <p:message for="input33" display="text"/>
        </h:panelGrid>
        <p:commandButton value="Submit" action="#{testPage.submitValidator}" update=":updateBody" />
    </div>

</h:form>

java class:

@FacesValidator(value="fooValidator")
public class CustomValidator2 implements Validator {

    @Override
    public void validate(FacesContext context, UIComponent component, Object value)
        throws ValidatorException {
    UIInput input1 = (UIInput) component.getAttributes().get("input1");
    UIInput input2 = (UIInput) component.getAttributes().get("input2");
    UIInput input3 = (UIInput) component.getAttributes().get("input3");

    Object value1 = input1.getSubmittedValue();
    Object value2 = input2.getSubmittedValue();
    Object value3 = input3.getSubmittedValue();

    if (value1.toString().isEmpty() && value2.toString().isEmpty() && value3.toString().isEmpty()) {
        String errorMsg = "fill in at least 1";
        FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, errorMsg, errorMsg);
        FacesContext.getCurrentInstance().addMessage("form1:input11", msg);
        //throw new ValidatorException(msg);
    }

    }
}

the code is working fine, but i face a problem. How to highlight border of name1 inputText(or both name1 and name2 inputText) with red color as usually done by JSF when validation fails.

image as reference: http://img443.imageshack.us/img443/8106/errork.jpg

thanks in advance

like image 408
heng heng Avatar asked Jan 17 '13 10:01

heng heng


People also ask

Which form needs custom validator directive that wrap validation function for form validation?

Reactive forms define custom validators as functions that receive a control to validate. Template-driven forms are tied to template directives, and must provide custom validator directives that wrap validation functions.

How to use custom form validation in Angular?

Using Validator in a Reactive Forms Instead of directives, Reactive Forms use functions for validation. First, open your terminal and use the @angular/cli package that was installed as a dev dependency to generate a new directive: ./node_modules/@angular/cli/bin/ng generate component reactive-form-example --flat.

What is cross field validation?

In simple words, making sure our data is correct by using multiple fields to check the validity of another. In fancier terms, this process is called Cross Field Validation. Sanity checking your dataset for data integrity is essential to have accurate analysis and running machine learning models.


1 Answers

Mark them invalid by UIInput#setValid(), passing false.

input1.setValid(false);
input2.setValid(false);
input3.setValid(false);

The borders are specific to PrimeFaces <p:inputText>, so you don't need to add any CSS boilerplate as suggested by the other answerer.

Note that this can also be achieved by OmniFaces <o:validateAll> tag without the need to homegrow a custom validator.

like image 167
BalusC Avatar answered Oct 23 '22 06:10

BalusC