PrimeFaces dataTable: how to catch rows-per-page event?

前端 未结 4 1750
小蘑菇
小蘑菇 2021-01-05 07:03

I cretated a PrimeFaces dataTable:



        
相关标签:
4条回答
  • 2021-01-05 07:43

    You can do that like this:

    The View

    <h:form id="mainForm">
    
        <p:dataTable id="locationTable" value="#{datatableBean.list}" var="item"
                     paginator="true" widgetVar="dtVar"
                     rows="#{datatableBean.rows}" 
                     paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                     rowsPerPageTemplate="1,2,3,4,5,6">
            <p:column>
                #{item.name}
            </p:column>
        </p:dataTable>
    
        <p:remoteCommand name="persistRows" action="#{datatableBean.saveRows}" process="@this" 
                         update="rows" global="false" />
    
        <h:outputText id="rows" value="#{datatableBean.rows}" />
    
        <script>
            jQuery(document).ready(function() {
                dtVar.paginator.rppSelect.change(function() {
                    persistRows([{name: 'rows', value: this.value}]);
                });
            });
        </script>
    </h:form>
    

    The Bean

    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import javax.annotation.PostConstruct;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.SessionScoped;
    import javax.faces.context.FacesContext;
    
    @ManagedBean
    @SessionScoped
    public class DatatableBean implements Serializable {
    
        private int rows;
    
        private List<SimpleBean> list;
    
        @PostConstruct
        public void setup() {
            //default rows value
            rows = 2;
    
            list = new ArrayList<SimpleBean>();
            //ID and Name
            list.add(new SimpleBean(11, "A"));
            list.add(new SimpleBean(22, "B"));
            list.add(new SimpleBean(33, "C"));
        }
    
        public void saveRows(){
            FacesContext context = FacesContext.getCurrentInstance();
            Map map = context.getExternalContext().getRequestParameterMap();
            String rowsStr = (String) map.get("rows");
            rows = Integer.parseInt(rowsStr);
        }
    
        public int getRows() {
            return rows;
        }
    
        public void setRows(int rows) {
            this.rows = rows;
        }
    
        public List<SimpleBean> getList() {
            return list;
        }
    
        public void setList(List<SimpleBean> list) {
            this.list = list;
        }
    
    }
    

    The strategy here is to extend the onchange event associated with the html select tags rendered by the paginator. To facilitate that task, I've set the wigetVar in the datatable (dtVar) knowing that it's clientside api gives us both selects through dtVar.paginator.rppSelect.

    Now, to be able to send the value on those selects to the managed bean, we can use a remoteCommand. Using the remoteCommand component we can send javascript parameters to a managedbean. I've named the remoteCommand as persistRows and by calling it I've specified the extra parameters using the pattern required by the component: [{name: 'rows', value: this.value}] ([{name: 'nameOfTheVariable', value: 'valueOfTheVariable'}]).

    Now you can do whatever you want to do with that rows attribute.

    0 讨论(0)
  • 2021-01-05 07:45

    I posted this solution to another question, and I'm sharing it because I hope someone might find it simpler to implement than Daniel's (which still taught me a lot about JQuery!)

    My solution is using Primefaces 5.2.x.

    I found a pretty easy way to implement this, one of the problems I had was that when the onPaginate() method was called, it didn't have the newest selected value.

    So here's what I did to make sure you always had the latest value and could save/load it to the database or a cookie or something (we save to a cookie).

    <p:dataTable
            .....
            paginator="true"
            paginatorPosition="bottom"
            paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
            currentPageReportTemplate="Total records: {totalRecords}, showing page {currentPage} of {totalPages}"
            rowsPerPageTemplate="25,50,100"
            rows="#{controller.rowsPerPage}"
            .....
        >
            .....
            <p:ajax event="page" oncomplete="rowsPerPageUpdate()" />
            .....
    </p:dataTable>
    <p:remoteCommand name="rowsPerPageUpdate" actionListener="#{controller.onPaginate}" />
    

    and then our controller looks like this:

    @Dependent
    @Named
    public class TableController implements Serializable {
        private String rowsPerPage = "25"; //default value
        .....
        public void onPaginate() {
            //save to the cookie
        }
        .....
    }
    

    Basically the magic happens in the remoteCommand, which will fire after the ajax event to insure that controller.rowsPerPage has been properly updated.

    0 讨论(0)
  • 2021-01-05 07:53

    I've searched for a solution too and after reading this thread I've found out that there's a new Primefaces feature which allows you to save the state of the datatable.

    So for Primefaces v6.0.10+ you can simply add multiViewState="true".

    Note that this will also save filter, sorting, current page and selection beside rows per page.

    Here's the link to the official demo of this feature: https://www.primefaces.org/showcase/ui/data/datatable/tableState.xhtml

    0 讨论(0)
  • 2021-01-05 07:58

    A simpler way that what is written above (tested with Primefaces 7.X) is to simply use the accessors method. This solution has the advantage to have the actual number of row being set. Otherwise, in my case I would obtain the previous number of row, before it is changed ...

    <p:dataTable
            .....
            paginator="true"
            paginatorPosition="bottom"
            paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
            currentPageReportTemplate="Total records: {totalRecords}, showing page {currentPage} of {totalPages}"
            rowsPerPageTemplate="25,50,100"
            rows="#{controller.rowsPerPage}"
            .....
        >
            .....
            .....
    </p:dataTable>
    

    And the bean should simply look like :

    @ViewScoped
    @Named
    public class Controller implements Serializable {
        private int rowsPerPage = 25; //default value
    
        public int getRowsPerPage() {
          return rowsPerPage;
        }
    
        /** Will be called each time the number or selected rows change */
        public void setRowsPerPage(int rows){
          this.rowsPerPage = rows; 
          // Do some other stuff, like using a cache to store the value
        }
    }
    

    I personally use a cache storing the number of rows per user and entity types.

    0 讨论(0)
提交回复
热议问题