2

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?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Thang Pham
  • 38,125
  • 75
  • 201
  • 285

2 Answers2

3

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.
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thank you, BalusC. It works. Can your omnifaces validator solve this problem? I was thinking about o:validateOrder, but I feel that it might not work since I need to first validate if the radio is selected or not – Thang Pham Aug 16 '12 at 14:21
  • There's nothing like that in OmniFaces. It's also a rather specific requirement. I'd personally rather have used `` or something. Note that there's also a `` which could replace `required="true"` this way. – BalusC Aug 16 '12 at 14:23
  • Hi BalusC. Just out of curious, what will be available in the validation phase. I feel like nothing is available during this phase, since validation is before Update model values phase. For example, if I just have a regular inputText, and I want to validate the value of what the user type in there, that value is not going to be set to my binding variable till update model phase. I still have to get it via request parameter map, do I not. Seems a bit silly to me. – Thang Pham Aug 20 '12 at 17:27
  • The component's own value which needs to be validated is just available as 3rd argument of `validate()` method. – BalusC Aug 20 '12 at 17:43
  • goshh, I know that. So silly. Thank you for that wake up call. – Thang Pham Aug 20 '12 at 18:42
  • @BalusC Can you explain it in depth by xhtml and java classes using JSF – spt Dec 11 '12 at 11:10
  • @ThangPham Can you explain it by using java classes and xhtml – spt Dec 11 '12 at 11:21
  • @spt The relevant code is already provided in both question and answer. If you have a specific question, please press `Ask Question` button. – BalusC Dec 11 '12 at 11:24
1

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.

Community
  • 1
  • 1
SJuan76
  • 24,532
  • 6
  • 47
  • 87