Home | Download | PDF | API | FAQ | Search | Feedback | History

> ## Registering Listeners on Components

> An application developer can implement listeners as classes or as backing bean methods. If a listener is a backing bean method, the page author references the method from either the component's valueChangeListener attribute or its actionListener attribute. If the listener is a class, the page author can reference the listener from either a `valueChangeListener` tag or an `actionListener` tag and nest the tag inside the component tag in order to register the listener on the component.

> Referencing a Method That Handles an Action Event and Referencing a Method That Handles a Value-change Event describe how a page author uses the valueChangeListener and actionListener attributes to reference backing bean methods that handle events.

> The Duke's Bookstore application includes a `ValueChangeListener` implementation class but does not use an `ActionListener` implementation class. This section explains how to register the `NameChanged` value-change listener and a hypothetical `LocaleChange` action listener implementation on components. Implementing Value-Change Listeners (page 399) explains how to implement `NameChanged`. Implementing Action Listeners (page 400) explains how to implement the hypothetical `LocaleChange` listener.

> ### Registering a Value-Change Listener on a Component

> A page author can register a `ValueChangeListener` implementation on a component that implements `EditableValueHolder` by nesting a `valueChangeListener` tag within the component's tag on the page. The `valueChangeListener` tag supports two attributes:

> - `type`: References the fully qualified class name of a `ValueChangeListener` implementation
> - `binding`: References an object that implements `ValueChangeListener`

> A page author must use one of these attributes to reference the value-change listener. The type attribute accepts a literal or a value expression. The binding attribute only accepts a value expression, which must point to a backing bean property that accepts and returns a `ValueChangeListener` implementation.

> Following is the tag corresponding to the `name` component from the `bookcashier.jsp` page. It uses the `type` attribute to reference a value-change listener:

>     <h:inputText  id="name" size="50" value="#{cashier.name}"
>       required="true">
>       <f:valueChangeListener type="listeners.NameChanged" />
>     </h:inputText>

> The `type` attribute specifies the custom NameChanged listener as the `ValueChangeListener` implementation to register on the `name` component.

> After this component tag is processed and local values have been validated, its corresponding component instance will queue the `ValueChangeEvent` associated with the specified `ValueChangeListener` to the component.

> The `binding` attribute is used to bind a `ValueChangeListener` implementation to a backing bean property. It works in a similar way to the `binding` attribute supported by the standard converter tags. Binding Component Values and Instances to External Data Sources explains more about binding listeners to backing bean properties.

> ### Registering an Action Listener on a Component

> A page author can register an `ActionListener` implementation on a `UICommand` component by nesting an `actionListener` tag within the component's tag on the page. Similarly to the `valueChangeListener` tag, the `actionListener` tag supports both the `type` and `binding` attributes. A page author must use one of these attributes to reference the action listener.

> Duke's Bookstore does not use any `ActionListener` implementations. Here is one of the `commandLink` tags on the `chooselocale.jsp` page, changed to reference an `ActionListener` implementation rather than a backing bean method:

>     <h:commandLink id="NAmerica" action="bookstore">
>        <f:actionListener type="listeners.LocaleChange" />
>     </h:commandLink>

> The `type` attribute of the `actionListener` tag specifies the fully qualified class name of the `ActionListener` implementation. Similarly to the `valueChangeListener` tag, the actionListener tag also supports the `binding` attribute. Binding Converters, Listeners, and Validators to Backing Bean Properties explains more about how to bind listeners to backing bean properties.

> When this tag's component is activated, the component's `decode` method (or its associated `Renderer`) automatically queues the `ActionEvent` implementation associated with the specified `ActionListener` implementation onto the component.

> In addition to the `actionListener` tag that allows you register a custom listener onto a component, the core tag library includes the `setPropertyActionListener` tag. You use this tag to register a special action listener onto the `ActionSource` instance associated with a component. When the component is activated, the listener will store the object referenced by the tag's value attribute into the object referenced by the tag's `target` attribute.

> The `bookcatalog.jsp` page uses `setPropertyActionListener` with two components: the `commandLink` component used to link to the `bookdetails.jsp` page and the `commandButton` component used to add a book to the cart:

>     <c:forEach items="#{bookDBAO.books}" var="book"
>       varStatus="stat">
>       <c:set var="book" scope="request" value="${book}"/>
>         ...
>       <h:commandLink action="#{catalog.details}"
>         value="#{book.title}">
>         <f:setPropertyActionListener
>           target="#{requestScope.book}" value="#{book}"/>
>       </h:commandLink>
>       ...
>       <h:commandButton id="add"
>         action="#{catalog.add}" value="#{bundle.CartAdd}">
>         <f:setPropertyActionListener
>           target="#{requestScope.book}" value="#{book}"/>
>       </h:commandButton>
>       <c:remove var="book" scope="request"/>
>     </c:forEach>

> As shown in the preceding code, the `commandLink` and `commandButton` components are within a `forEach` tag, which iterates over the list of books. The `var` attribute refers to a single book in the list of books.

> The object referenced by the `var` attribute of a `forEach` tag is in page scope. However, in this case, you need to put this object into request scope so that when the user activates the `commandLink` component to go to `bookdetails.jsp` or activates the `commandButton` component to go to `bookcatalog.jsp`, the book data is available to those pages. Therefore, the `setPropertyActionListener` tag is used to set the current `book` object into request scope when the `commandLink` or `commandButton` component is activated.

> In the preceding example, the `setPropertyActionListener` tag's `value` attribute references the `book` object. The `setPropertyActionListener` tag's `target` attribute references the value expression `requestScope.book`, which is where the `book` object referenced by the `value` attribute is stored when the `commandLink` or the `commandButton` component is activated.