I would like to have a ‘Show All’ button for a primefaces datatable, however, I’m experiencing some trouble. Here’s some test code that demostrates the problem:
Test.xhtml:
... <h:form> <p:selectBooleanCheckbox value="#{testBean.showAll}" itemLabel="Show All"> <p:ajax update="@form"/> </p:selectBooleanCheckbox> <p:panel id="test"> <p:dataTable id="values" var="value" value="#{testBean.fullList}" filteredValue="#{testBean.filteredList}" paginatorAlwaysVisible="false" paginator="#{!testBean.showAll}" rows="#{!testBean.showAll ? 2 : null }" widgetVar="valuesTable" emptyMessage="No records found."> <p:column id="enum" sortBy="#{value.toString()}" filterBy="#{value.toString()}" filterMatchMode="contains"> <f:facet name="header"> <h:outputText value="Enum" /> </f:facet> <h:outputText value ="#{value.toString()}"/> </p:column> <p:column id="name" sortBy="#{value.name}" filterBy="#{value.name}" filterMatchMode="contains"> <f:facet name="header"> <h:outputText value="Name" /> </f:facet> <h:outputText value="#{value.name}" /> </p:column> </p:dataTable> </p:panel> </h:form> ...
And here’s TestBean.java:
import javax.inject.Named; import javax.enterprise.context.SessionScoped; import java.io.Serializable; import java.util.Arrays; import java.util.List; @Named(value = "testBean") @SessionScoped public class TestBean implements Serializable { public static enum Value { ONE, TWO, THREE; public String getName() { return name().toLowerCase(); } @Override public String toString() { return this.name(); } } /** * Creates a new instance of TestBean */ public TestBean() { } private boolean showAll = false; private List<Value> fullList = Arrays.asList(Value.values()); private List<Value> filteredList; public boolean isShowAll() { return showAll; } public void setShowAll(boolean showAll) { this.showAll = showAll; } public List<Value> getFullList() { return fullList; } public void setFullList(List<Value> fullList) { this.fullList = fullList; } public List<Value> getFilteredList() { return filteredList; } public void setFilteredList(List<Value> filteredList) { this.filteredList = filteredList; } }
If I don’t change tabs, the page works as expected: toggling the ‘Show All’ button updates the table to show all 3 values, or only two. However, if show all is not checked (only 2 rows are showing), and I click to the 2nd page of the table to view the third record, and then click ‘Show All’, the table does not update properly. It removes the paginator from the top of the table (as expected), but still only shows the 3rd record. And if I then uncheck show all and navigate back to the first page of the datatable, it is now broken too.
I’ve tried changing the ajax update statement to the id of the table, but that didn’t change the results.
Am I doing something wrong? Thanks in advance.
Advertisement
Answer
You have to programmatically set the values you need directly on the DataTable
component (I used explicit first
and rows
bean properties just for more readability):
<h:form> <p:selectBooleanCheckbox value="#{testBean.showAll}" itemLabel="Show All"> <p:ajax update="@form" /> </p:selectBooleanCheckbox> <p:panel id="test"> <p:dataTable id="values" var="value" value="#{testBean.fullList}" filteredValue="#{testBean.filteredList}" paginatorAlwaysVisible="false" paginator="#{!testBean.showAll}" first="#{testBean.first}" rows="#{testBean.rows}" widgetVar="valuesTable" emptyMessage="No records found."> <p:column id="enum" sortBy="#{value.toString()}" filterBy="#{value.toString()}" filterMatchMode="contains"> <f:facet name="header"> <h:outputText value="Enum" /> </f:facet> <h:outputText value="#{value.toString()}" /> </p:column> <p:column id="name" sortBy="#{value.name}" filterBy="#{value.name}" filterMatchMode="contains"> <f:facet name="header"> <h:outputText value="Name" /> </f:facet> <h:outputText value="#{value.name}" /> </p:column> </p:dataTable> </p:panel> </h:form>
and
@Named @ViewScoped public class TestBean implements Serializable { private static final long serialVersionUID = 1L; public static enum Value { ONE, TWO, THREE; public String getName() { return name().toLowerCase(); } @Override public String toString() { return name(); } } private boolean showAll = false; private int first = 0; private int rows = 2; private List<Value> fullList = Arrays.asList(Value.values()); private List<Value> filteredList; public boolean isShowAll() { return showAll; } public void setShowAll(boolean showAll) { this.showAll = showAll; first = 0; rows = showAll ? 0 : 2; filteredList = null; // get the FacesContext instance FacesContext context = FacesContext.getCurrentInstance(); // get the current component (p:selectBooleanCheckbox) UIComponent component = UIComponent.getCurrentComponent(context); // find DataTable within the same NamingContainer DataTable table = (DataTable) component.findComponent("values"); // reset first row index table.setFirst(first); // reset last row index table.setRows(rows); // reset filterd value table.setFilteredValue(null); } // all other getters/setters }
Tested on Wildfly 10.0.0.Final with JSF 2.3.0-m06 (Mojarra) and PrimeFaces 6.0.2