TableState feature enables DataTable to maintain its state across pages by setting multiViewState attribute to true. In this demo, manipulate table with pagination, sorting, filtering and selection, then visit another page and then come back to this page. DataTable state should remain as you've left it.
Documentation<style type="text/css"> .ui-datatable .ui-datatable-header { text-align: right !important; } .ui-selectcheckboxmenu-panel .ui-selectcheckboxmenu-header .ui-chkbox { display: none; } </style> <h:form id="form"> <p:messages id="messages" /> <p:dataTable id="tableStateDT" var="car" value="#{dtTableStateView.cars}" widgetVar="carsTable" multiViewState="true" rows="10" paginator="true" paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="5,10,15" selectionMode="single" selection="#{dtTableStateView.selectedCar}" rowKey="#{car.id}" emptyMessage="No cars found with given criteria" filteredValue="#{dtTableStateView.filteredCars}"> <f:facet name="header"> <p:outputPanel> <h:outputText value="Search all fields:" /> <p:inputText id="globalFilter" onkeyup="PF('carsTable').filter()" style="width:150px" placeholder="Enter keyword"/> </p:outputPanel> </f:facet> <p:ajax event="rowSelect" update=":form:carDetail" oncomplete="PF('carDialog').show()" /> <p:column headerText="Id" filterBy="#{car.id}" sortBy="#{car.id}" filterMatchMode="contains"> <h:outputText value="#{car.id}" /> </p:column> <p:column headerText="Year" filterBy="#{car.year}" sortBy="#{car.year}" filterMatchMode="startsWith"> <h:outputText value="#{car.year}" /> </p:column> <p:column headerText="Brand" filterBy="#{car.brand}" sortBy="#{car.brand}" filterMatchMode="exact"> <f:facet name="filter"> <p:selectOneMenu onchange="PF('carsTable').filter()" style="width:100%; box-sizing: border-box;" > <f:selectItem itemLabel="Select One" itemValue="#{null}" noSelectionOption="true" /> <f:selectItems value="#{dtTableStateView.brands}" /> </p:selectOneMenu> </f:facet> <h:outputText value="#{car.brand}" /> </p:column> <p:column headerText="Color" filterBy="#{car.color}" sortBy="#{car.color}" filterMatchMode="in"> <f:facet name="filter"> <p:selectCheckboxMenu label="Colors" onchange="PF('carsTable').filter()" style="width:100%; box-sizing: border-box;" scrollHeight="150"> <f:selectItems value="#{dtTableStateView.colors}" /> </p:selectCheckboxMenu> </f:facet> <h:outputText value="#{car.color}" /> </p:column> <f:facet name="paginatorTopLeft"> <p:commandButton value="Clear table state" action="#{dtTableStateView.clearTableState}" update="@form"/> </f:facet> </p:dataTable> <br /> with LazyDataModel: <p:dataTable var="car" value="#{dtLazyView.lazyModel}" paginator="true" rows="10" paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}" rowsPerPageTemplate="5,10,15" id="carTable" lazy="true" multiViewState="true"> <p:column headerText="Id" sortBy="#{car.id}" filterBy="#{car.id}"> <h:outputText value="#{car.id}" /> </p:column> <p:column headerText="Year" sortBy="#{car.year}" filterBy="#{car.year}"> <h:outputText value="#{car.year}" /> </p:column> <p:column headerText="Brand" sortBy="#{car.brand}" filterBy="#{car.brand}"> <h:outputText value="#{car.brand}" /> </p:column> <p:column headerText="Color" sortBy="#{car.color}" filterBy="#{car.color}"> <h:outputText value="#{car.color}" /> </p:column> <f:facet name="paginatorTopLeft"> <p:commandButton value="Clear table state" action="#{dtTableStateView.clearTableState}" update="@form"/> </f:facet> </p:dataTable> <p:dialog header="Car Info" widgetVar="carDialog" modal="true" showEffect="fade" hideEffect="fade" resizable="false"> <p:outputPanel id="carDetail" style="text-align:center;"> <p:panelGrid columns="2" rendered="#{not empty dtTableStateView.selectedCar}" columnClasses="label,value"> <f:facet name="header"> <p:graphicImage name="demo/images/car/#{dtTableStateView.selectedCar.brand}-big.gif"/> </f:facet> <h:outputText value="Id:" /> <h:outputText value="#{dtTableStateView.selectedCar.id}" /> <h:outputText value="Year" /> <h:outputText value="#{dtTableStateView.selectedCar.year}" /> <h:outputText value="Brand" /> <h:outputText value="#{dtTableStateView.selectedCar.brand}" /> <h:outputText value="Color:" /> <h:outputText value="#{dtTableStateView.selectedCar.color}" style="color:#{dtTableStateView.selectedCar.color}"/> </p:panelGrid> </p:outputPanel> </p:dialog> </h:form>
@Named("dtTableStateView") @SessionScoped public class TableStateView implements Serializable { private List<Car> cars; private List<Car> filteredCars; private Car selectedCar; @Inject private CarService service; @PostConstruct public void init() { cars = service.createCars(50); } public List<String> getBrands() { return service.getBrands(); } public List<String> getColors() { return service.getColors(); } public List<Car> getCars() { return cars; } public List<Car> getFilteredCars() { return filteredCars; } public Car getSelectedCar() { return selectedCar; } public void setSelectedCar(Car selectedCar) { this.selectedCar = selectedCar; } public void setFilteredCars(List<Car> filteredCars) { this.filteredCars = filteredCars; } public void setService(CarService service) { this.service = service; } public void clearTableState() { FacesContext context = FacesContext.getCurrentInstance(); String viewId = context.getViewRoot().getViewId(); PrimeFaces.current().multiViewState().clearAll(viewId, true, (clientId) -> { showMessage(clientId); }); } private void showMessage(String clientId) { FacesContext.getCurrentInstance() .addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, clientId + " multiview state has been cleared out", null)); } }
public class Car implements Serializable { public String id; public String brand; public int year; public String color; public int price; public boolean sold; public Car() {} public Car(String id, String brand, int year, String color) { this.id = id; this.brand = brand; this.year = year; this.color = color; } public Car(String id, String brand, int year, String color, int price, boolean sold) { this.id = id; this.brand = brand; this.year = year; this.color = color; this.price = price; this.sold = sold; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } public boolean isSold() { return sold; } public void setSold(boolean sold) { this.sold = sold; } @Override public int hashCode() { int hash = 7; hash = 59 * hash + (this.id != null ? this.id.hashCode() : 0); return hash; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Car other = (Car) obj; if ((this.id == null) ? (other.id != null) : !this.id.equals(other.id)) { return false; } return true; } }
@Named @ApplicationScoped public class CarService { private final static String[] colors; private final static String[] brands; static { colors = new String[10]; colors[0] = "Black"; colors[1] = "White"; colors[2] = "Green"; colors[3] = "Red"; colors[4] = "Blue"; colors[5] = "Orange"; colors[6] = "Silver"; colors[7] = "Yellow"; colors[8] = "Brown"; colors[9] = "Maroon"; brands = new String[10]; brands[0] = "BMW"; brands[1] = "Mercedes"; brands[2] = "Volvo"; brands[3] = "Audi"; brands[4] = "Renault"; brands[5] = "Fiat"; brands[6] = "Volkswagen"; brands[7] = "Honda"; brands[8] = "Jaguar"; brands[9] = "Ford"; } public List<Car> createCars(int size) { List<Car> list = new ArrayList<Car>(); for(int i = 0 ; i < size ; i++) { list.add(new Car(getRandomId(), getRandomBrand(), getRandomYear(), getRandomColor(), getRandomPrice(), getRandomSoldState())); } return list; } private String getRandomId() { return UUID.randomUUID().toString().substring(0, 8); } private int getRandomYear() { return (int) (Math.random() * 50 + 1960); } private String getRandomColor() { return colors[(int) (Math.random() * 10)]; } private String getRandomBrand() { return brands[(int) (Math.random() * 10)]; } private int getRandomPrice() { return (int) (Math.random() * 100000); } private boolean getRandomSoldState() { return (Math.random() > 0.5) ? true: false; } public List<String> getColors() { return Arrays.asList(colors); } public List<String> getBrands() { return Arrays.asList(brands); } }
@Named("dtLazyView") @ViewScoped public class LazyView implements Serializable { private LazyDataModel<Car> lazyModel; private Car selectedCar; @Inject private CarService service; @PostConstruct public void init() { lazyModel = new LazyCarDataModel(service.createCars(200)); } public LazyDataModel<Car> getLazyModel() { return lazyModel; } public Car getSelectedCar() { return selectedCar; } public void setSelectedCar(Car selectedCar) { this.selectedCar = selectedCar; } public void setService(CarService service) { this.service = service; } public void onRowSelect(SelectEvent<Car> event) { FacesMessage msg = new FacesMessage("Car Selected", event.getObject().getId()); FacesContext.getCurrentInstance().addMessage(null, msg); } }