Reputation: 271
Just wanted to ask for the best way to solve my problem: I got a form with multiple inputs/selects and also buttons to add new objects to the databean behind the form. Now my problem is the validation. E.g.: in one of those selects i chose an option. If this option is selected the user has to add a specific type of an object to the large databean behind the form. That's done by selecting values in two further selects. As soon as those are selected (they are submitted onchange by ajax) the user generates a new object by hitting an "Add" button.
On submit those added object (consisting of two values) must have a specific enum type depending on the first selected value and so on..
Now this all (and a lot more) should be validated and error/info messages should be added to the view.
Now my question: whats the best way to achieve this? The error message has to be at a specific place in the view.
I thought of multiple hidden input
fields and using the validate
attribute to call validation methods of the underlying bean (cause bean values are needed too). And then rendering an error message right at the position of the hidden field. Is this a good solution? Working with the validator
attribute and validating the whole form would lead to error messages in areas where the user hasn't made any input yet, right? I would like to avoid that and just validate the current area. Is that possible by using one bean? Otherwise i would have to use multiple validators with a lot of attributes, or use the beanManager to get my underlying bean?
Upvotes: 0
Views: 1756
Reputation: 12505
The JSF validation is done per component, not per form. This is by design (and it has a good purposes). There is a lot of misunderstanding on this point and many teams make the mistake of shoehorning their business logic validation into component validation, just because the word "validation" sounds right to them.
The validation you need is different - it's a business level validation. You don't really validate state of a single component, but rather coherence of the data, which is behind the components. You can still use the message framework to display the errors where you want them.
The clean and "proper" way to do it in JSF will be to:
skip the JSF component validation (because it's designed for different case than yours); you want all the values from the component to be put into your backing beans;
put anywhere you need an error message displayed;
write validation logic in your action method. You can use Bean Validation Framework or write the logic by hand;
if no errors are found, the action method performs an action;
on error, depending on the error, display a message in a proper place (using the component id);
if any error occured, don't perform the action and return from the action method.
The action method should look somewhat like this (this is not a copy-paste example, it's just to give you an idea of the flow):
public void doSomething() {
boolean valid = true;
if (startData.after(expiryDate)) {
FacesContext.getCurrentInstance().addMessage("expiryDate", new FacesMessage("Expiry date should come after creation date"));
valid = false;
}
// other checks
// checks could also make use of BVF validator - but then it's better to switch the BFV validation for the whole form
// (if you don't, then any single field validation will disable error checking for the business validation, which
// will look strange for your users)
if (!valid) {
// if we returned immediately upon detecting an error, we would only display the first one.
return;
}
// do the real stuff
}
Upvotes: 1