简体   繁体   English

PrimeFaces dataTable:如何捕获 rows-per-page 事件?

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

I cretated a PrimeFaces dataTable:我创建了一个 PrimeFaces 数据表:

<p:dataTable id="locationTable" value="#{bean.object}" var="item"
  paginator="true"
  rows="10" 
  paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink}{LastPageLink} {RowsPerPageDropdown}" 
  rowsPerPageTemplate="5,10,15,20,30,50,100">
  ...
</p:dataTable>

I'd like to save the dropdown box value for rows-per-page.我想保存每页行的下拉框值。 When the user changes the value, how would I catch the event?当用户更改值时,我将如何捕获事件? So I can read and save one of the "5,10,15,20,30,50,100" values in order for this to apear automatically next time the user comes back to this page.所以我可以读取并保存“5,10,15,20,30,50,100”值之一,以便下次用户返回此页面时自动出现。 Currently, it is not saved, so every time the page is (re)loaded, it goes back to default value of "10".目前,它没有保存,因此每次(重新)加载页面时,它都会返回默认值“10”。

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. 这里的策略是扩展与paginator呈现的html 选择标记关联的onchange事件。 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 . 为了促进这项任务,我在数据表( dtVar )中设置了wigetVar,知道它的客户端api通过dtVar.paginator.rppSelect给我们两个选择。

Now, to be able to send the value on those selects to the managed bean, we can use a remoteCommand. 现在,为了能够将这些选择的值发送到托管bean,我们可以使用remoteCommand。 Using the remoteCommand component we can send javascript parameters to a managedbean. 使用remoteCommand组件,我们可以将javascript参数发送到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'}]). 我将remoteCommand命名为persistRows并通过调用它使用组件所需的模式指定了额外的参数: [{name:'rows',value:this.value}] ([{name:'nameOfTheVariable' ,value:'valueOfTheVariable'}])。

Now you can do whatever you want to do with that rows attribute. 现在,您可以使用该行属性执行任何操作。

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!) 我将此解决方案发布到另一个问题,我正在分享它,因为我希望有人可能会发现实现起来比Daniel更简单(它仍然教会了我很多关于JQuery的东西!)

My solution is using Primefaces 5.2.x. 我的解决方案是使用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. 我找到了一种非常简单的方法来实现它,我遇到的一个问题是,当调用onPaginate()方法时,它没有最新的选定值。

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). 所以这就是我所做的,以确保您始终拥有最新的价值,并可以将其保存/加载到数据库或cookie或其他东西(我们保存到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. 基本上魔术发生在remoteCommand中,它将在ajax事件之后触发,以确保controller.rowsPerPage已正确更新。

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. 我也在寻找解决方案,在阅读完这篇文章之后,我发现有一个新的Primefaces功能可以让你保存数据表的状态。

So for Primefaces v6.0.10+ you can simply add multiViewState="true" . 因此,对于Primefaces v6.0.10 +,您只需添加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 这是此功能的官方演示的链接: https//www.primefaces.org/showcase/ui/data/datatable/tableState.xhtml

A simpler way that what is written above (tested with Primefaces 7.X) is to simply use the accessors method. 上面写的(使用Primefaces 7.X测试)的简单方法是简单地使用访问器方法。 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 : 而bean应该看起来像:

@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. 我个人使用缓存来存储每个用户和实体类型的行数。

I have simple solution like this我有这样的简单解决方案

<p:dataTable

.....

<p:ajax event="page" listener="#{yourBean.onPaginate}" />

...
 </p:dataTable>

This is your bean这是你的豆子

public void onPaginate(PageEvent event)
    {
        String pageSizeParam = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("parameter name");

....

With "parameter name", you can check on F12, Network tab -> payload使用“参数名称”,您可以检查 F12,网络选项卡 -> 有效负载

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM