Immediate Components

   

In "Life-Cycle Events" on page 274 we saw that value change events are normally fired after the Process Validations phase and action events are normally fired after the Invoke Application phase. Typically, that's the preferred behavior you usually want to be notified of value changes only when they are valid, and actions should be invoked after all submitted values have been transmitted to the model.

But sometimes you want value change events or action events to fire at the beginning of the life cycle to bypass validation for one or more components. In "Using Immediate Input Components" and "Using Immediate Command Components" on page 295 we make compelling arguments for such behavior. For now, let's look at the mechanics of how immediate events are delivered, as illustrated by Figure 7-6.

Figure 7-6. Immediate Components

graphics/07fig06.jpg


Immediate events are fired after the Apply Request Values phase. For input components, conversion and validation are performed after the Apply Request Values phase and value change events are subsequently fired. For command components, action listeners are invoked, followed by actions; that process kicks in the navigation handler and circumvents the rest of the life cycle up to Render Response.

Using Immediate Input Components

Figure 7-7 shows the value change example discussed in "Value Change Events" on page 275. Recall that the application uses a value change listener to change the view's locale, which in turn changes the localized state prompt according to the selected locale.

Figure 7-7. An Immediate Need

graphics/07fig07.jpg


Here we've made a seemingly innocuous change to that application: we added a required validator to the Address field and added a message tag to the form. But that validation results in an error when we select a country without filling in the Address field (recall that the country menu submits its form when its value is changed).

The problem is this: We want validation to kick in when the submit button is activated, but not when the country is changed. How can we specify validation for one but not the other?

The solution is to make the country menu an immediate component. Immediate input components perform conversion and validation and subsequently deliver value change events at the beginning of the JSF life cycle after the Apply Request Values phase instead of after Process Validations.

We specify immediate components with the immediate attribute, which is available to all input and command components:

 

 <h:selectOneMenu value="#{form.country}" onchange="submit()" immediate="true"     valueChangeListener="#{form.countryChanged}">     <f:selectItems value="#{form.countryNames}"/> </h:selectOneMenu> 

With the immediate attribute set to true, our menu fires value change events after Apply Request Values, well before any other input components are validated. You may wonder what good that does us if the other validations happen later instead of sooner after all, the validations will still be performed and the validation error will still be displayed. To prevent validations for the other components in the form, we have one more thing to do: call the faces context renderResponse method at the end of our value change listener, like this:

 

 private static final String US = "United States"; ... public void countryChanged(ValueChangeEvent event) {     FacesContext context = FacesContext.getCurrentInstance();     if(US.equals(event.getNewValue()))          context.getViewRoot().setLocale(Locale.US);       else          context.getViewRoot().setLocale(Locale.CANADA);       context.renderResponse();    } } 

The call to renderResponse() skips the rest of the life cycle including validation of the rest of the input components in the form up to Render Response. Thus, the other validations are skipped and the response is rendered normally (in this case, the current page is redisplayed).

To summarize, you can skip validation when a value change event fires by doing the following:

  1. Adding an immediate attribute to your input tag

  2. Calling FacesContext.renderResponse() at the end of your listener

Using Immediate Command Components

In Chapter 4 we discussed an application, shown in Figure 7-8, that uses command links to change locales.

Figure 7-8. Changing Locales with Links

graphics/07fig08.jpg


If we add a required validator to one of the input fields in the form, we'll have the same problem we had with the application discussed in "Using Immediate Input Components" on page 294: the validation error will appear when we just want to change the locale by clicking on a link. This time, however, we need an immediate command component instead of an immediate input component. All we need to do is add an immediate attribute to our h:commandLink tag, like this:

 

 <h:commandLink actionListener="#{localeChanger.changeLocale}" immediate="true">     <h:graphicImage value="/german_flag.gif" style="border: 0px"/>     <f:param name="locale" value="german"/> </h:commandLink> 

Unlike value change events, we do not need to modify our listener to invoke FacesContext.renderResponse(), because all actions, immediate or not, proceed directly to the Render Response phase, regardless of when they are fired.



core JavaServer Faces
Core JavaServer Faces
ISBN: 0131463055
EAN: 2147483647
Year: 2003
Pages: 121

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net