Reputation: 2191
If I have many input controls in a form (There are separate validators for each of these input controls - like required,length and so on ) , there is a command button which submits the form and calls an action method. The requirement is - though the input control values are , say , individually okay - the combination of these values should be okay to process them together after the form submission - Where do i place the code to validate them together?
1) Can i add a custom validator for the command button and validate the combination together? like validate(FacesContext arg0, UIComponent arg1, Object value)
but even then I will not have values of the other input controls except for the command button's/component's value right ?
2) can i do the validation of the combination in the action method and add validation messages using FacesMessage
?
or do you suggest any other approach?
Thanks for your time.
Upvotes: 3
Views: 5995
Reputation: 13245
I've just landed on your post after having the same question.
Articles I have read so far identify that there are four types of validation for the following purposes:
With reference to Validators: The validation mechanism in JSF was designed to validate a single component. (See S/O Question here)
In the case where you want to validate a whole form as a logical grouping of fields, it appears with standard JSF/Apache MyFaces that the most appropriate to do it is as Application Validation, as the set of individual fields take on a collective business meaning at this point.
BalusC has come up with a way of shoehorning form validation into a single validator attached to the last form item (again, see S/O Question here and another worked example on his website here) however it isn't necessarily extensible/reusable, as the references to the ID's of the form have to be hardcoded as you can't append to the validate() method's signature. You'll get away with it if you're only using the form once, but if it pops up a few times or if you generate your ID's programmatically, you're stuck.
The JSF implementation portion of Seam has a <s:validateForm />
control which can take the IDs of fields elsewhere in your form as parameters. Unfortunately, it doesn't appear that any of the MyFaces/Mojara/Sun JSF implementations have an equivalent as it isn't part of the standard.
Upvotes: 5
Reputation: 1109645
Point 2 is already answered by Bozho. Just use FacesContext#addMessage()
. A null
client ID will let it land in <h:messages globalOnly="true">
. A fixed client ID like formId:inputId
will let it land in <h:message for="inputId">
.
Point 1 is doable, you can grab the other components inside the validator method using UIViewRoot#findComponent()
:
UIInput otherInput = (UIInput) context.getViewRoot().findComponent("formId:otherInputId");
String value = (String) otherInput.getValue();
You however need to place f:validator
in the last UIInput
component. Placing it in an UICommand
component (like the button) won't work.
True, hardcoding the client ID's is nasty, but that's the payoff of a bit inflexible validation mechanism in JSF.
Upvotes: 5
Reputation: 597382
I've successfully used the 2nd approach:
FacesMessage facesMessage =
new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
Upvotes: 3