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 anactionListener
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 anActionListener
implementation class. This section explains how to register theNameChanged
value-change listener and a hypotheticalLocaleChange
action listener implementation on components. Implementing Value-Change Listeners (page 397) explains how to implementNameChanged
. Implementing Action Listeners (page 398) explains how to implement the hypotheticalLocaleChange
listener.Registering a Value-Change Listener on a Component
A page author can register a
ValueChangeListener
implementation on a component that implementsEditableValueHolder
by nesting avalueChangeListener
tag within the component's tag on the page. ThevalueChangeListener
tag supports two attributes: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 thebookcashier.jsp
page. It uses thetype
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 theValueChangeListener
implementation to register on thename
component.After this component tag is processed and local values have been validated, its corresponding component instance will queue the
ValueChangeEvent
associated with the specifiedValueChangeListener
to the component.The
binding
attribute is used to bind aValueChangeListener
implementation to a backing bean property. It works in a similar way to thebinding
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 aUICommand
component by nesting anactionListener
tag within the component's tag on the page. Similarly to thevalueChangeListener
tag, theactionListener
tag supports both thetype
andbinding
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 thecommandLink
tags on thechooselocale.jsp
page, changed to reference anActionListener
implementation rather than a backing bean method:<h:commandLink id="NAmerica" action="bookstore"> <f:actionListener type="listeners.LocaleChange" /> </h:commandLink>The
type
attribute of theactionListener
tag specifies the fully qualified class name of theActionListener
implementation. Similarly to thevalueChangeListener
tag, the actionListener tag also supports thebinding
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 associatedRenderer
) automatically queues theActionEvent
implementation associated with the specifiedActionListener
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 thesetPropertyActionListener
tag. You use this tag to register a special action listener onto theActionSource
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'starget
attribute.The
bookcatalog.jsp
page usessetPropertyActionListener
with two components: thecommandLink
component used to link to thebookdetails.jsp
page and thecommandButton
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
andcommandButton
components are within aforEach
tag, which iterates over the list of books. Thevar
attribute refers to a single book in the list of books.The object referenced by the
var
attribute of aforEach
tag is in page scope. However, in this case, you need to put this object into request scope so that when the user activates thecommandLink
component to go tobookdetails.jsp
or activates thecommandButton
component to go tobookcatalog.jsp
, the book data is available to those pages. Therefore, thesetPropertyActionListener
tag is used to set the currentbook
object into request scope when thecommandLink
orcommandButton
component is activated.In the preceding example, the
setPropertyActionListener
tag'svalue
attribute references thebook
object. ThesetPropertyActionListener
tag'starget
attribute references the value expressionrequestScope.book
, which is where thebook
object referenced by thevalue
attribute is stored when thecommandLink
or thecommandButton
component is activated.