Passing Data from the UI to the Server

Immediate Components

In "Life Cycle Events" on page 268, 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 is 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" on page 288 and "Bypassing Validation" on page 237, we make compelling arguments for such behavior. For now, we will look at the mechanics of how immediate events are delivered, as illustrated by Figure 7-6.

Figure 7-6. Immediate components


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 269. 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. Unwanted validation


Here we have 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 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, which is to 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((String) 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

One more thing is noteworthy about this example. Notice that we add an onchange attribute whose value is submit() to our h:selectOneMenu tag. Setting that attribute means that the JavaScript submit function will be invoked whenever someone changes the selected value of the menu, which causes the surrounding form to be submitted.

That form submit is crucial because the JSF implementation handles all events on the server. If you take out the onchange attribute, the form will not be submitted when the selected menu item is changed, meaning that the JSF life cycle will never be invoked, our value change listener will never be called, and the locale will never be changed.

You may find it odd that JSF handles all events on the server, but remember that you can handle events on the client if you wish by attaching JavaScript to components with attributes such as onblur, onfocus, onclick, etc. Also, client-side event handling is on the table for the next version of JSF.

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


If we add a required validator to one of the input fields in the form, we will have the same problem we had with the application discussed in "Using Immediate Input Components" on page 288: The validation error will appear when we just want to change the locale by clicking 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 action="#{localeChanger.germanAction}" immediate="true">      <h:graphicImage value="/german_flag.gif" style="border: 0px"/>   </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 JavaServerT Faces
Core JavaServer(TM) Faces (2nd Edition)
ISBN: 0131738860
EAN: 2147483647
Year: 2004
Pages: 84

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