Thang Pham
Thang Pham

Reputation: 38705

JSF: How to validate an inputText only when another component is selected

I have three radio buttons, an inputText and a submit button. I only want to validate the input text on submit when a certain radio is selected. So I have

<h:inputText validator="#{myBean.validateNumber}" ... />

And in my bean I have

 public void validateNumber(FacesContext context, UIComponent component,
                Object value) throws ValidatorException{
      if(selectedRadio.equals("Some Value"){
           validate(selectedText);
      }
 }

 public void validate(String number){
      if (number != null && !number.isEmpty()) {
        try {
            Integer.parseInt(number);
        } catch (NumberFormatException ex) {
            throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
                "Error", "Not a number."));
        }
      } else {
        throw new ValidatorException(new FacesMessage(FacesMessage.SEVERITY_ERROR,
                "Error", "Value is required."));
      }
 }

The one thing that make this not work is that when I submit, validateNumber(...) runs before my setter method for the radio button setSelectedRadio(String selectedRadio). Therefore causing this statements

 if(selectedRadio.equals("Some Value"){
       validate(selectedText);
 }

to not execute correctly. Any idea on how to get around this problem?

Upvotes: 2

Views: 3810

Answers (2)

BalusC
BalusC

Reputation: 1109332

The selectedRadio is as being a model value only updated during update model values phase, which is after the validations phase. That's why it's still the initial model value while you're trying to examine it.

You'd have to grab it from either the request parameter map (which is the raw submitted value), or the UIInput reference, so that you can get either the submitted value by getSubmittedValue() or the converted/validated value by getValue().

So,

String selectedRadio = externalContext.getRequestParameterMap().get("formId:radioId");

or

UIInput radio = (UIInput) viewRoot.findComponent("formId:radioId"); // Could if necessary be passed as component attribute.
String submittedValue = radio.getSubmittedValue(); // Only if radio component is positioned after input text, otherwise it's null if successfully converted/validated.
// or
String convertedAndValidatedValue = radio.getValue(); // Only if radio component is positioned before input text, otherwise it's the initial model value.

Upvotes: 3

SJuan76
SJuan76

Reputation: 24895

It is called cross-field validation (validate not only based in the value of a component, but a set of them).

Currently, JSF2 does not support it ( JSF doesn't support cross-field validation, is there a workaround? ) but there are several libraries (in the refered question omnifaces is mentioned, it looks like seamfaces also has something for it) that might help. Also in the question there is a workaround.

Upvotes: 1

Related Questions