# The Java EE 7 Tutorial

# 11.2 Registering Listeners on Components

An application developer can implement listeners as classes or as managed bean methods. If a listener is a managed 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 an `f:valueChangeListener` tag or an `f:actionListener` tag and nest the tag inside the component tag 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 explain how a page author uses the `valueChangeListener` and `actionListener` attributes to reference managed bean methods that handle events.

This section explains how to register a `NameChanged` value-change listener and a `BookChange` action listener implementation on components. The Duke's Bookstore case study includes both of these listeners.

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

A page author can register a `ValueChangeListener` implementation on a component that implements `EditableValueHolder` by nesting an `f:valueChangeListener` tag within the component's tag on the page. The `f:valueChangeListener` tag supports the attributes shown in Table 11-4, one of which must be used.

Table 11-4 Attributes for the f:valueChangeListener Tag

Attribute | Description
--- | ---
`type` | References the fully qualified class name of a `ValueChangeListener` implementation. Can accept a literal or a value expression.
`binding` | References an object that implements `ValueChangeListener`. Can accept only a value expression, which must point to a managed bean property that accepts and returns a `ValueChangeListener` implementation.

The following example shows a value-change listener registered on a component:

    <h:inputText id="name"
                 size="30"
                 value="#{cashierBean.name}"
                 required="true"
                 requiredMessage="#{bundle.ReqCustomerName}">
        <f:valueChangeListener
            type="javaeetutorial.dukesbookstore.listeners.NameChanged" />
    </h:inputText>

In the example, the core tag `type` attribute specifies the custom `NameChanged` listener as the `ValueChangeListener` implementation registered 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 managed bean property. This attribute works in a similar way to the `binding` attribute supported by the standard converter tags. See Binding Component Values and Instances to Managed Bean Properties for more information.

## 11.2.2 Registering an Action Listener on a Component

A page author can register an `ActionListener` implementation on a command component by nesting an `f:actionListener` tag within the component's tag on the page. Similarly to the `f:valueChangeListener` tag, the `f:actionListener` tag supports both the `type` and `binding` attributes. One of these attributes must be used to reference the action listener.

Here is an example of an `h:commandLink` tag that references an `ActionListener` implementation:

    <h:commandLink id="Duke" action="bookstore">
        <f:actionListener
            type="javaeetutorial.dukesbookstore.listeners.LinkBookChangeListener" />
        <h:outputText value="#{bundle.Book201}"/>
    </h:commandLink>

The `type` attribute of the `f:actionListener` tag specifies the fully qualified class name of the `ActionListener` implementation. Similarly to the `f:valueChangeListener` tag, the `f:actionListener` tag also supports the `binding` attribute. See Binding Converters, Listeners, and Validators to Managed Bean Properties for more information about binding listeners to managed bean properties.

In addition to the `actionListener` tag that allows you register a custom listener onto a component, the core tag library includes the `f: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.xhtml` page of the Duke's Bookstore application uses `f:setPropertyActionListener` with two components: the `h:commandLink` component used to link to the `bookdetails.xhtml` page and the `h:commandButton` component used to add a book to the cart:

    <h:dataTable id="books"
        value="#{store.books}"
        var="book"
        headerClass="list-header"
        styleClass="list-background"
        rowClasses="list-row-even, list-row-odd"
        border="1"
        summary="#{bundle.BookCatalog}" >
        ...
        <h:column>
            <f:facet name="header">
                <h:outputText value="#{bundle.ItemTitle}"/>
            </f:facet>
            <h:commandLink action="#{catalog.details}"
                           value="#{book.title}">
                <f:setPropertyActionListener target="#{requestScope.book}"
                                             value="#{book}"/>
            </h:commandLink>
        </h:column>
        ...
        <h:column>
            <f:facet name="header">
                <h:outputText value="#{bundle.CartAdd}"/>
            </f:facet>
            <h:commandButton id="add"
                             action="#{catalog.add}"
                             value="#{bundle.CartAdd}">
                <f:setPropertyActionListener target="#{requestScope.book}"
                                             value="#{book}"/>
            </h:commandButton>
        </h:column>

The `h:commandLink` and `h:commandButton` tags are within an `h:dataTable` 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 an `h:dataTable` 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.xhtml` or activates the `commandButton` component to go to `bookcatalog.xhtml`, the book data is available to those pages. Therefore, the `f: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 `f:setPropertyActionListener` tag's `value` attribute references the `book` object. The `f: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.