Why does you need to choose to validate all UIInput components on one form or to validate none at all?
the immedaite attribute for UICommand component is really useful only in case you need to bypass all validations and updates on the form like cancel buttons, but if you need to validate only fiew UIInput components on the form you need to use immediate="true" and use manual validation and backing bean update using values returned from myInput.getSubmittedValue() property!
Why doesn't JSF use "partial" validation & update like Microsoft does for ASP.NET 2.0 using validationGroup property?
Also Oracle ADF Faces component set implement a subform tag to bypass validation & update in a more flexible way but their solution have a layout constraint. Infact it force validation of a set of components that can be nested into a single subform tag.
I have implemented an approach similar to Microsoft ASP.NET 2.0 (with no layout constraint) using a custom HtmlCommandButton component with validationList attribute and a custom HtmlForm component.
The validationList attribute of the HtmlCommandButton is a comma separated list of UIInput id you want to process during Process Validations and Update Model Values phases.
The decode() method of the HtmlCommandButton put this list into requestMap under a predefined key.
The custom form component is a standard form like HtmlForm of the reference implementation (you can also inherit from HtmlForm) but customize (or override) processValidators(FacesContext context) and processUpdates(FacesContext context) methods to recursively call the same methods only for childen wich have id present in the validation list. These are the custom form methods:
validationListAttribute is the string comma separated list of components id to validate.
Any comment to this solution is appreciated.
Originally posted by Gregg Bolinger:
I am not clear on why you state that you have to validate all fields or none at all. I have several forms with dozens of fields on each form. Some are validated on submit, some are not and all with the standard validation components. Can you clarify what you mean?
I'll try to explain what I mean for "validate all fields or none at all".
Imagine you have a web application with a simple page with a simple input form;
in this form you have some UIInput components to take user input, value bounded to a backing-bean;
some of these components are required and each component may or may not use a converter and one or more validators.
On this form you have one UICommand component (for example a commandButton or commandLink) to save the form and one other to cancel and navigate to another page.
In such a simple, monolithic form, with very limited user interaction, you could feel good with JSF simple approach to convertion/validation an model update. Infact, you can use a commandButton with immediate="false" for the save button and a commandButton with immediate="true" for the cancel button.
But imagine you need a more sophisticated user interaction during form input; for example, you may have two or more UISelectOne component that dynamically submit the form to enable or render other components or to update other components state (for example to fill other UISelectOne components).
You certanly need to use some sort of "immediate" and getSubmittedValue() trick to read values from the interactive portion of the page the user is editing because you don't want to trigger other components convertion and/or validation errors and you may need to manually convert and/or validate these components values you want to read. Moreover, if you decide to use immediate="true" / onchange="this.form.submit()" / valueChangeListener combination on more than one component (for example on two UISelectOne) and these components are required (and initially blank) you cannot change the value of one these without throwing a validation error on the other one.
Originally posted by Gregg Bolinger:
So in the value changed listener method for the dropdown lists, just call renderResponse() from the FacesContext object and validation and conversion is bypassed and you can still do what you want. I think you are making the issue more complicated than what it is?
obviously you have to call renderResponse() at the end of the valueChangeListener of the two UISelectOne but this don't change the behavior descripted. Infact if you have such situation
changing one of the selectOneMenu you can bypass conversion, validation and update of inputText fields (for example you have no required message from "name" field) but you can't bypass the other selectOneMenu convertion and validation because all convertion and validation of immediate UIInput components are executed during appply request values phase (responseComplete() is evaluated at the end of each phase to bypass next phase but current phase must be completed). You can avoid immediate="true" on the two selectoneMenu and use an hidden UICommand with immediate="true" and an action or actionListener, calling "this.form['myform:mybutton'].click()" instead of this.form.submit() in the two selectOneMenu but you need manual convertion/validation/update of values obtained from getSubmittedValue(). if your item values aren't simple String, for example java.util.Date objects, and you use a DateTimeConverter it would be convenient to use it.
Did you wonder why Oracle propose a subform component in ADF faces?
You can solve all this problems with Orcle subform and (probably better) with the simple solution I posted.