PrimeFaces dataTable:如何捕获每页行数事件?

时间:2014-01-27 13:11:55

标签: jsf primefaces

我创建了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>

我想保存每页行数的下拉框值。当用户更改值时,我该如何捕获该事件?因此,我可以读取并保存其中一个“5,10,15,20,30,50,100”值,以便下次用户返回此页面时自动显示该值。目前,它没有保存,因此每次(重新)加载页面时,它都会恢复为默认值“10”。

4 个答案:

答案 0 :(得分:6)

你可以这样做:

视图

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

}

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

现在,为了能够将这些选择的值发送到托管bean,我们可以使用remoteCommand。使用remoteCommand组件,我们可以将javascript参数发送到managedbean。我将remoteCommand命名为 persistRows 并通过调用它使用组件所需的模式指定了额外的参数: [{name:'rows',value:this.value }] ([{name:'nameOfTheVariable',value:'valueOfTheVariable'}])。

现在,您可以使用该行属性执行任何操作。

答案 1 :(得分:1)

我将此解决方案发布到另一个问题上,并且我正在分享它,因为我希望有人可能会发现实施起来比Daniel更简单(它仍然教会了我很多关于JQuery的内容!)

我的解决方案是使用Primefaces 5.2.x。

我找到了一种非常简单的方法来实现它,我遇到的一个问题是,当调用onPaginate()方法时,它没有最新选择的值。

所以这就是我所做的,以确保您始终拥有最新的价值并可以将其保存/加载到数据库或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}" />

然后我们的控制器看起来像这样:

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

基本上魔法发生在remoteCommand中,它将在ajax事件之后触发,以确保controller.rowsPerPage已正确更新。

答案 2 :(得分:0)

我也在寻找解决方案,并且在阅读了该主题之后,我发现有一个新的Primefaces功能可以让您保存数据表的状态。

因此对于Primefaces v6.0.10 +,您只需添加multiViewState="true"

请注意,这还将在每页行旁边保存过滤器,排序,当前页面和选择。

以下是此功能的官方演示的链接:https://www.primefaces.org/showcase/ui/data/datatable/tableState.xhtml

答案 3 :(得分:0)

上面编写的(使用Primefaces 7.X测试的)更简单的方法是简单地使用accessors方法。该解决方案的优点是可以设置实际的行数。否则,就我而言,我将获得之前的行数,然后再进行更改...

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

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
    }
}

我个人使用缓存来存储每个用户和实体类型的行数。