views:

32

answers:

1

I have two fields representing data range ("from" and "to"). I need to check if either both fields are filled on none of them, so only moment there should be validation message shown is when one is filled and not second one. How can I do that? I thied this custom validator and add it to both fields (as JSF doesn't validate empty fields) but it always show that they are not valid.

public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
  String otherControlId = (String) component.getAttributes().get("otherControlId");
  UIInput otherControlInput = (UIInput) context.getViewRoot().findComponent(otherControlId);
  Object otherControlValue = otherControlInput.getValue();
  if ((value == null && otherControlValue != null) || (value != null && otherControlValue == null)) {
 //show message
  }
}

otherControlId points to second control ID, and I get a control in validator. But otherControlValue is always null.

+1  A: 

Components are processed in the order as they appear in the component tree. So if the otherControlInput appears after the currently validated component in the component tree, then it's not processed yet. You would then need to access its (unconverted and unvalidated!) value by UIInput#getSubmittedValue() instead of UIInput#getValue().

Object otherControlValue = otherControlInput.getSubmittedValue();

An alternative is to put the validator on the other component (the one that appears the last in the tree) instead of the current component, then you can get the value by UIInput#getValue().

A completely different alternative is to let required attribute depend on each other:

<h:inputText binding="#{from}" value="#{bean.from}" required="#{not empty to.submittedValue}" />
<h:inputText binding="#{to}" value="#{bean.to}" required="#{not empty from.value}" />
BalusC
This would explain situation when I would always get one message. But when two fields are filled, both of them trigger validator.
Migol
Then check both the `submittedValue` and `value`. I've updated the answer with a different alternative, probably more suitable in your case.
BalusC
Ok, I fixed it. If first control validator is fired then value is in UIInput#getSubmittedValue(). If it is fired on second control then UIInput#getSubmittedValue() returns null, but value is in UIInput#getValue(). Thanks for help, fix your answer and I will mark is.
Migol
You're welcome, but my answer already contains this information in the first paragraph.
BalusC