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
valueChangeListenertag or anactionListenertag 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
ValueChangeListenerimplementation class but does not use anActionListenerimplementation class. This section explains how to register theNameChangedvalue-change listener and a hypotheticalLocaleChangeaction listener implementation on components. Implementing Value-Change Listeners (page 397) explains how to implementNameChanged. Implementing Action Listeners (page 398) explains how to implement the hypotheticalLocaleChangelistener.Registering a Value-Change Listener on a Component
A page author can register a
ValueChangeListenerimplementation on a component that implementsEditableValueHolderby nesting avalueChangeListenertag within the component's tag on the page. ThevalueChangeListenertag 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
ValueChangeListenerimplementation.Following is the tag corresponding to the
namecomponent from thebookcashier.jsppage. It uses thetypeattribute 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
typeattribute specifies the custom NameChanged listener as theValueChangeListenerimplementation to register on thenamecomponent.After this component tag is processed and local values have been validated, its corresponding component instance will queue the
ValueChangeEventassociated with the specifiedValueChangeListenerto the component.The
bindingattribute is used to bind aValueChangeListenerimplementation to a backing bean property. It works in a similar way to thebindingattribute 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
ActionListenerimplementation on aUICommandcomponent by nesting anactionListenertag within the component's tag on the page. Similarly to thevalueChangeListenertag, theactionListenertag supports both thetypeandbindingattributes. A page author must use one of these attributes to reference the action listener.Duke's Bookstore does not use any
ActionListenerimplementations. Here is one of thecommandLinktags on thechooselocale.jsppage, changed to reference anActionListenerimplementation rather than a backing bean method:<h:commandLink id="NAmerica" action="bookstore"> <f:actionListener type="listeners.LocaleChange" /> </h:commandLink>The
typeattribute of theactionListenertag specifies the fully qualified class name of theActionListenerimplementation. Similarly to thevalueChangeListenertag, the actionListener tag also supports thebindingattribute. 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
decodemethod (or its associatedRenderer) automatically queues theActionEventimplementation associated with the specifiedActionListenerimplementation onto the component.In addition to the
actionListenertag that allows you register a custom listener onto a component, the core tag library includes thesetPropertyActionListenertag. You use this tag to register a special action listener onto theActionSourceinstance 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'stargetattribute.The
bookcatalog.jsppage usessetPropertyActionListenerwith two components: thecommandLinkcomponent used to link to thebookdetails.jsppage and thecommandButtoncomponent 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
commandLinkandcommandButtoncomponents are within aforEachtag, which iterates over the list of books. Thevarattribute refers to a single book in the list of books.The object referenced by the
varattribute of aforEachtag is in page scope. However, in this case, you need to put this object into request scope so that when the user activates thecommandLinkcomponent to go tobookdetails.jspor activates thecommandButtoncomponent to go tobookcatalog.jsp, the book data is available to those pages. Therefore, thesetPropertyActionListenertag is used to set the currentbookobject into request scope when thecommandLinkorcommandButtoncomponent is activated.In the preceding example, the
setPropertyActionListenertag'svalueattribute references thebookobject. ThesetPropertyActionListenertag'stargetattribute references the value expressionrequestScope.book, which is where thebookobject referenced by thevalueattribute is stored when thecommandLinkor thecommandButtoncomponent is activated.