1 Reply Latest reply on Mar 19, 2013 5:19 AM by senthil_sss

    DataTable with serverside Pagination, MultipleSorting, Filtering

    senthil_sss

      Hi frnds, i tried LazyDataModel multiple column sort using PrimeFaces 3.5

      My XHTML coding:-

       

          <p:dataTable var="iterator" id="agencyDataTable"

                              value="#{LazyAgencyDataModel}"

                              paginator="true" rows="20"

                              rowsPerPageTemplate="20,40,100" first="0" paginatorPosition="top"

                              paginatorAlwaysVisible="true" filterEvent="keyup" filterDelay="2000"

                              sortEvent="keyup"

                              paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"

                              lazy="true"  sortMode="multiple">

       

       

      my backing managed bean:-

       

       

          @Override

          public List<T> load(int first, int pageSize, List<SortMeta> multiSortMeta,Map<String, String> filters) {

          ....}

       

      this works perfectly giving multisort results in my first page, but fails to carry the List<SortMeta> multiSortMeta(multiple sorting details to load method) values when i paginate.

       

       

      can anyone help to fix this...

       

      or any other way exist there in richfaces to overcome this ....

      Thanks in advance

        • 1. Re: DataTable with serverside Pagination, MultipleSorting, Filtering
          senthil_sss

          i have a testcase ready with MINIMAL WORKING and this is my testcase..

           

          i just enabled multiple sorting in the showcase code for "DataTable - Lazy Loading"

           

          datatableLazy.xhtml

          [code]

          <html lang="en" xmlns="http://www.w3.org/1999/xhtml"

              xmlns:f="http://java.sun.com/jsf/core"

              xmlns:h="http://java.sun.com/jsf/html"

              xmlns:p="http://primefaces.org/ui"

              xmlns:ui="http://java.sun.com/jsf/facelets">

          <h:head>

              <title>CarDataTable</title>

          </h:head>

          <h:body>

              <h:form id="form">

                  <p:dataTable var="car" value="#{tableBean.lazyModel}" paginator="true"

                      rows="10"

                      paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"

                      rowsPerPageTemplate="5,10,15" id="carTable" lazy="true"

                      sortMode="multiple">

           

                      <p:ajax event="rowSelect" listener="#{tableBean.onRowSelect}"

                          update=":form:display" oncomplete="carDialog.show()" />

           

                      <p:column headerText="Model" sortBy="#{car.model}"

                          filterBy="#{car.model}">

                          <h:outputText value="#{car.model}" />

                      </p:column>

           

                      <p:column headerText="Year" sortBy="#{car.year}"

                          filterBy="#{car.year}">

                          <h:outputText value="#{car.year}" />

                      </p:column>

           

                      <p:column headerText="Manufacturer" sortBy="#{car.manufacturer}"

                          filterBy="#{car.manufacturer}">

                          <h:outputText value="#{car.manufacturer}" />

                      </p:column>

           

                      <p:column headerText="Color" sortBy="#{car.color}"

                          filterBy="#{car.color}">

                          <h:outputText value="#{car.color}" />

                      </p:column>

                  </p:dataTable>

              </h:form>

          </h:body>

          </html>

          [/code]

           

           

          TableBean.java

           

          [code]

          package com.solartis.primefaces.sample;

           

          import java.util.ArrayList;

          import java.util.List;

          import java.util.UUID;

           

          import javax.faces.bean.ManagedBean;

           

          import org.primefaces.model.LazyDataModel;

           

          @ManagedBean

          public class TableBean {

           

              private LazyDataModel<Car> lazyModel;

           

              private Car selectedCar;

           

              private List<Car> cars = new ArrayList<Car>();

           

              private final static String[] colors;

           

              private final static String[] manufacturers;

           

              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";

           

                  manufacturers = new String[10];

                  manufacturers[0] = "Mercedes";

                  manufacturers[1] = "BMW";

                  manufacturers[2] = "Volvo";

                  manufacturers[3] = "Audi";

                  manufacturers[4] = "Renault";

                  manufacturers[5] = "Opel";

                  manufacturers[6] = "Volkswagen";

                  manufacturers[7] = "Chrysler";

                  manufacturers[8] = "Ferrari";

                  manufacturers[9] = "Ford";

              }

           

              public TableBean() {

                  populateRandomCars(cars, 50);

                  lazyModel = new LazyCarDataModel(cars);

              }

           

              public Car getSelectedCar() {

                  return selectedCar;

              }

           

              public void setSelectedCar(Car selectedCar) {

                  this.selectedCar = selectedCar;

              }

           

              public LazyDataModel<Car> getLazyModel() {

                  return lazyModel;

              }

           

              private void populateRandomCars(List<Car> list, int size) {

                  for (int i = 0; i < size; i++) {

                      list.add(new Car(getRandomModel(), getRandomYear(),

                              getRandomManufacturer(), getRandomColor()));

                  }

              }

           

              private String getRandomColor() {

                  return colors[(int) (Math.random() * 10)];

              }

           

              private String getRandomManufacturer() {

                  return manufacturers[(int) (Math.random() * 10)];

              }

           

              private int getRandomYear() {

                  return (int) (Math.random() * 50 + 1960);

              }

           

              private String getRandomModel() {

                  return UUID.randomUUID().toString().substring(0, 8);

              }

          }

          [/code]

           

          LazyCarDataModel.java

          [code]

          package com.solartis.primefaces.sample;

           

          import java.util.ArrayList;

           

          /**

          * Dummy implementation of LazyDataModel that uses a list to mimic a real datasource like a database.

          */

          public class LazyCarDataModel extends LazyDataModel<Car> {

             

              private List<Car> datasource;

             

              public LazyCarDataModel(List<Car> datasource) {

                  this.datasource = datasource;

              }

             

              @Override

              public Car getRowData(String rowKey) {

                  for(Car car : datasource) {

                      if(car.getModel().equals(rowKey))

                          return car;

                  }

           

                  return null;

              }

           

              @Override

              public void setRowIndex(int rowIndex) {

           

                  if (rowIndex == -1 || getPageSize() == 0) {

                      super.setRowIndex(-1);

                  } else

                      super.setRowIndex(rowIndex % getPageSize());

              }

             

              @Override

              public Object getRowKey(Car car) {

                  return car.getModel();

              }

           

              @Override

              public List<Car> load(int first, int pageSize, List<SortMeta> multiSortMeta,Map<String, String> filters) {

                 

                  System.out.println("\nTHE INPUT PARAMETER VALUE OF LOAD METHOD : \t"+"first=" + first + ", pagesize=" + pageSize + ", multiSortMeta=" + multiSortMeta + " filter:" + filters);

                 

                  System.out.println("\nTHE MULTISORTMETA CONTENT  : \t");

                 

                  if (multiSortMeta != null) {

                      for (SortMeta sortMeta : multiSortMeta) {

                          System.out.println("SORTFIELD:" +sortMeta.getSortField());

                          System.out.println("SORTORDER:" +sortMeta.getSortOrder());

                          System.out.println("SORTFUNCTION:" +sortMeta.getSortFunction());

                          System.out.println("COLUMN:" +sortMeta.getColumn());

                          System.out.println("CLASS:" +sortMeta.getClass());

                      }

                  }

                 

                  List<Car> data = new ArrayList<Car>();

           

                  //filter

                  for(Car car : datasource) {

                      boolean match = true;

           

                      for(Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {

                          try {

                              String filterProperty = it.next();

                              String filterValue = filters.get(filterProperty);

                              String fieldValue = String.valueOf(car.getClass().getField(filterProperty).get(car));

           

                              if(filterValue == null || fieldValue.startsWith(filterValue)) {

                                  match = true;

                              }

                              else {

                                  match = false;

                                  break;

                              }

                          } catch(Exception e) {

                              match = false;

                          }

                      }

           

                      if(match) {

                          data.add(car);

                      }

                  }

           

           

                  //rowCount

                  int dataSize = data.size();

                  this.setRowCount(dataSize);

           

                  //paginate

                  if(dataSize > pageSize) {

                      try {

                          return data.subList(first, first + pageSize);

                      }

                      catch(IndexOutOfBoundsException e) {

                          return data.subList(first, first + (dataSize % pageSize));

                      }

                  }

                  else {

                      return data;

                  }

              }

          }

          [/code]

           

          and as expected it works well except the below situation

           

          "when i paginate with multiple columns sorting,  the load method (with "List<SortMeta>")does not give me the column details which are currently sorted to carry over to the other page, unlike the load method (with "String sortField,SortOrder sortOrder") which gives those sorting details."

           

          for example:-

          1. click on the sorting arrow in "manufacturer" and then ctrl+click on the sorting arrow of "year"

               - u would get the sorting column details to the load method (i have printed the input parameters value inside load method).

           

          2. Now, do pagination.Here the load method fails to give the sorting columns detail

              - not only for pagination, if u enter column filter values after clicking on the sorting columns, the same problem exist

           

           

          can any one help me to fix this ..

          Thanks in advance