问题
I am trying implement an "Add item to Cart" functionality for alist f items displayed on page using <p:dataList>
. The add button is a p:selectBooleanButton.
I have attached an ajax listener to the button to add current item to a collection in my backing bean. However, the listener method is not being invoked but the button rendering updates.
Attaching a valueChangeListener
works but I assume I should not be using it?
However, in either case my pagination stops working. Clicking on any of the pagination buttons does not change the page content.
Could someone please assist with the same or suggest a better approach?
Following is the code:
Backing Bean
@ManagedBean(name = "movies")
@ViewScoped
public class MovieListBean extends BaseBean implements Serializable
{
private static final long serialVersionUID = -1887386711644123475L;
private LazyDataModel<Movie> lazyModel;
private Map<Integer, Rental> cart;
@PostConstruct
public void initialize() {
cart = new HashMap<>(0);
}
public LazyDataModel<Movie> getLazyModel()
{
if (lazyModel == null)
{
lazyModel = new LazyDataModel<Movie>() {
private static final long serialVersionUID = -858683609299266223L;
@Override
public List<Movie> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters)
{
List<Movie> movieList = serviceLocator.getMovieService().getMovieCatalogInRange(first, (first + pageSize));
this.setRowCount(serviceLocator.getMovieService().getCatalogSize());
return movieList;
}
};
}
return lazyModel;
}
public void updateCart(Object obj)
{
System.out.println("Selected Movie ID" + obj);
if (lazyModel != null)
{
System.out.println("Selected row in datalist - " + lazyModel.getRowIndex());
System.out.println("Object instance associated with selected row - " + lazyModel.getRowData());
}
// Process object instance and add to cart
}
public Map<Integer, Rental> getCart() {
return cart;
}
public void setCart(Map<Integer, Rental> cart) {
this.cart = cart;
}
}
index.xhtml
<ui:composition template="/WEB-INF/templates/template.xhtml">
<ui:define name="content">
<h:outputStylesheet name="movies.css" library="styles" />
<h:form prependId="false" id="form">
<p:dataList value="#{movies.lazyModel}" var="movie" id="movies" paginator="true" rows="10"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}"
type="none" paginatorAlwaysVisible="false" lazy="true">
<p:panel id="movieInfo">
<h:outputText value="#{movie.movieName}" styleClass="titles" />
<div id="infoContainer">
<div>
<h:graphicImage library="images" name="#{movie.imageUri}" />
</div>
<div>
<div>
<h:outputText value="#{movie.plotLine}" />
</div>
<div class="rating">
<span>Rating : </span>
<p:rating value="#{movie.rating}" stars="10" readonly="true" />
</div>
<div id="rent">
<p:selectBooleanButton offLabel="Add to Cart" onLabel="Remove from Cart" id="btnRent"
value="#{not empty movies.cart[movie.movieID]}">
<p:ajax update="btnRent" listener="#{movies.updateCart (movie.movieID)}" event="click"/>
</p:selectBooleanButton>
</div>
</div>
</div>
</p:panel>
</p:dataList>
</h:form>
</ui:define>
</ui:composition>
I am using JSF 2.1 (Mojarra) + Primefaces 3.5
回答1:
Value of your p:selectBooleanButton
is #{not empty movies.cart[movie.movieID]}
. This is not possible. It should be a Boolean lvalue, some property with getter and setter. How you think JSF will set field when it is sent with AJAX? As this buttons are in datatable you can organize their values as array of Boolean.
来源:https://stackoverflow.com/questions/15053370/ajax-listener-not-being-fired-for-pselectbooleanbutton-inside-pdatalist