Purpose of Immediate
I came across questions regarding the usage the "immediate" in forum
postings as well as from a few
Creator customers. I hope this blog addresses some of the
questions around the usage of "immediate" as well as its use cases.
Purpose of Immediate
The "immediate" is provided on UICommand components to control page
flow through standard navigation rules while bypassing validation and
update model values altogether. On UIInput components, "immediate" is
provided to process validation earlier than normal namely
ProcessValidations
Phase.
Usage of Immediate on UICommand Components.
Typically you set "immediate" attribute on UICommand components when
you are implementing wizards that have optional steps (such as when the
user clicks the "Skip/Cancel" button to advance to the next view) or in
cases where the user wants to cancel out the values entered in input
fields of a form for some reason. In this scenario, there is no purpose
in validating the input fields and update the properties that the input
components are bound to. All you want to do is to proceed to the next
operation. "immediate" flag on UICommand component makes this possible
by forcing action to be invoked during the apply request values phase
before the process validations phase (rather than during the invoke
application phase, which occurs after the process validations phase).
Note that conversion/validation will still be excecuted for input
components that have "immediate" set to true because setting
"immediate" on UIInput components causes validation to be triggered
during apply request values phase. Depending on how you have configured
your navigation rules, you will either navigate to the next view in the
page or display the same page if its a "Cancel" operation. If the same
page re renders you will notice that the values you entered before
clicking on the "Cancel/Skip" button are ignored.
Important Note
By default, when you set immediate to true on a command
component, when the page gets redisplayed, submitted values of all
input components will be
retained because as per JSF Spec, only validation/updates will be
skipped. If you don't values to be retained, you have to explicitly
erase the values. If you are using Creator, you can make use of the
erase() method from your immediate button's action handler which will
erase the submitted value on all input components in the page. If you
are not using Creator, you have set call setSubmittedValue(null)
on all input components in the page.
public String button1_action() {
this.erase();
return null;
}
Technical/Implementation Details
During decode, ActionEvents are queued by the UICommand component
that caused the form to be
submitted. UICommand.queueEvent() sets the PhaseId on this ActionEvent
to Apply Request Values if "immediate" is set. So this forces the
ActionEvent?
to be handled during ApplyRequestValues
which in turn causes the navigation rules to be executed right away
instead of during Invoke Applications Phase.
Usage of Immediate on UIInput Components.
When you set "immediate" to true on UIInput components,
conversion/validation would occur earlier in the lifecycle once the
values have been decoded. (during ApplyRequestValues
Phase). Consequently value change events for those components also get
queued during ApplyRequest?
Values. There is no other change in the lifecycle (unlike setting
"immediate" on UICommand component which causes conversion/validation
to be skipped). Any converters/validators set on non "immediate"
components will still be executed as usual during ProcessValidations
phase. If you have two components with dependencies, you may need to
set "immediate" on both components depending on the use case. This
feature is provided for managing dynamic input fields like lists. Lets
consider an example. You have a page with a checkbox, a dropdown and a
button. You want to dynamically populate the second dropdown and pre
select a value if the checkbox is checked. Assume you also have a
validator attached to the dropdown. If so, you need to have the list
populated before validators are processed on the dropdown. This is
where "immediate" comes in handy. If you have "immediate" set on the
checkbox, value change event gets fired during ApplyRequestValues.
In the process_ValueChange of the check box, the list can be populated
and a value can be pre-selected. During ProcessValidations
any validators set on the dropdown can now be executed without any
surprises. Lets look another application "immediate". You have page
with textfield and a dropdown. You want to populate and validate the
text field when the dropdown changes. To acheive this, you have to set
"immediate" to true on the dropdown so that you can set the value of
the textfield in ValueChangeListener
of the dropdown which will get executed before ProcessValidations
on the textfield because of "immediate".
Technical/Implementation Details
UIInput.processDecodes() (executed during ApplyRequestValues
phase) calls decode on the component. Once the decode exits, this
method checks to see if "immediate" is set, if so executes
conversion/validation immediately. If conversion/validation failed,
then validation/update model values phase will be skipped and the
control will jump to Render response phase once all the components in
the view have been decoded. If valadation is successful, the
"immediate" input component will have its submitted value set as local
value at the end of ApplyRequest
Values phase. During ProcessValidations
phase, only non "immediate" components will be validated.
Special case, dropdown with "auto submit on change"
If you have an application with drop down lists that submits when
the
make a selection, irrespective whether you have immediate set on the
components are not, all the validators will be executed except that the
"immediate" components will have their convertors/validators triggered
right after decode as explained in the previous section. Setting
"immediate" on the input fields in the form will not help you to by
pass validation in this case. You alternative is to make your
validators execute conditionally when the page is submitted via
"Submit" button.