type=page
status=published
title=Registering Listeners on Components
next=jsf-page-core003.html
prev=jsf-page-core001.html
~~~~~~
= Registering Listeners on Components


[[BNASZ]]

[[registering-listeners-on-components]]
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.

link:jsf-page-core004.html#BNATQ[Referencing a Method That Handles an
Action Event] and link:jsf-page-core004.html#BNATS[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.

[[BNATA]]

[[registering-a-value-change-listener-on-a-component]]
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
link:#GKCLY[Table 11-5], one of which must be used.

[[sthref64]][[GKCLY]]

*Table 11-5 Attributes for the f:valueChangeListener Tag*

[width="60%",cols="10%,50%"]
|=======================================================================
|*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:

[source,oac_no_warn]
----
<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 link:jsf-custom013.html#BNATG[Binding Component
Values and Instances to Managed Bean Properties] for more information.

[[BNATB]]

[[registering-an-action-listener-on-a-component]]
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:

[source,oac_no_warn]
----
<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
link:jsf-custom014.html#BNATM[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:

[source,oac_no_warn]
----
<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.
