15

I've a datatable in primefaces and I want, when I add a row in it, view the last page of the datatable.

My .xhtml page is:

<h:form id=...>
...
<p:dataTable var="webTemplate" id="templateTable" widgetVar="tbl1"/>
...
</h:form>

<h:form id=...>
...
<p:inputText id="txt_description" value="#{templateController.templateDescription}" label="templateDescription">
               <f:validateLength for="txt_name" minimum="1"/>
               <p:ajax event="change"
                     listener="#{calculatePageTable.setPageTableTemplate}"  onsuccess="setTabIndexTT()"/>
               </p:inputText>
...
</h:form>
<script type="text/javascript">
      function setTabIndexTT(){
                    tbl1.getPaginator().setPage(#{calculatePageTable.pageTableTemplate});
                }
      </script>

bean:

@ManagedBean
@SessionScoped
public class CalculatePageTable {

   private int pageTableTemplate = 0;
   private int pageTableField = 0;

   public void setPageTableTemplate() {

      final DataTable d = (DataTable) FacesContext.getCurrentInstance().getViewRoot()
            .findComponent("form:templateTable");
      pageTableTemplate = d.getPageCount() - 1;

   }

   public int getPageTableTemplate() {
      return pageTableTemplate;
   }

   public void setPageTemplateField() {

      final DataTable d = (DataTable) FacesContext.getCurrentInstance().getViewRoot()
            .findComponent("detailsTable:webTemplateUpdateTable");
      pageTableField = (d.getPageCount() - 1);
   }

   public int getPageTableField() {
      return pageTableField;
   }

}

But the js function setTabIndexTT() is never called by onsuccess ajax...

How do I can set last page of my datatable when adding a row?

Primefaces version is 3.1.1

Kukeltje
  • 12,223
  • 4
  • 24
  • 47
3vi
  • 420
  • 1
  • 4
  • 21

4 Answers4

14

In your managed bean you can try this code:

public void setPageDataTable() {
    final DataTable d = (DataTable) FacesContext.getCurrentInstance().getViewRoot()
        .findComponent("form:templateTable");
    int first = 1;
    if (d.getRowCount() % ROWS_DATATABLE == 0) {
        first = (d.getRowCount() - ROWS_DATATABLE);
    }
    else 
    {
        first = (d.getRowCount()/ROWS_DATATABLE)*ROWS_DATATABLE;
    }
    d.setFirst(first);
}

Call this method when you add a new row

Teg
  • 1,302
  • 13
  • 32
  • 1
    +1 for the `d.setFirst(first);`. In my case, I've used: `((DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent("myForm").findComponent("myDataTable")).setFirst(0)` to go to the first page every time I refresh the content. – falsarella Sep 27 '12 at 11:38
  • May I know what is `ROWS_DATATABLE` indicating here ?? confused – Qadir Hussain Nov 24 '14 at 08:53
  • I guess using the binding-attribute of the primefaces-datatable makes the code above more clean (no hardcoded ids) – L. Monty Aug 11 '15 at 15:10
  • How can you change the datatable page? This code only puts the last entered row at the beginning. – Renato Espinoza Carranza Apr 15 '16 at 17:46
7

if the datatable widgetVar is dataTableWidget then use this:

<script type="text/javascript">
            $(document).ready(function () {
                dataTableWidget.paginator.setPage(0);
            });
 </script>
ehsan
  • 787
  • 3
  • 13
  • 26
  • See also: https://stackoverflow.com/a/33413948/1599699 `PF('dataTableWV').paginator.setPage(PF('dataTableWV').paginator.cfg.pageCount - 1);` `RequestContext.getCurrentInstance().execute("PF('dataTableWV').paginator.setPage(PF('dataTableWV').paginator.cfg.pageCount - 1);");` – Andrew Aug 27 '18 at 16:30
2

I would do it without any JavaScript. Primefaces's datatable has a first attribute, which is the index of the first data to display.

<p:dataTable first="#{calculatePageTable.first}"/>
...
<p:commandButton value="Add a row" action="#{calculatePageTable.addRow}"/>

And your backing bean:

public class CalculatePageTable {
    private int first = 1;

    public int getFirst(){
        return first;
    }

    public void addRow(){
        // 1. your stuff for adding the row 
        ...
        // 2. switch to the row
        first = getFirstRowOnLastPage(); 
    }

    private int getFirstRowOnLastPage(){
        ...
    }
}
fischermatte
  • 3,327
  • 4
  • 42
  • 52
  • but getFirst() when is invoked? Only first time the datatable is render? If I change page with paginator, afet getFirst() isn't invkoed... – 3vi Apr 05 '12 at 12:25
  • You are right, i've overseen that. this solution only works when your backing bean is session scoped (which is the case in your sample) and the `addRow` action creates a new view. You can do this by returning the current viewId instead of defining `addRow` as void. – fischermatte Apr 05 '12 at 13:47
  • just write ‘return "myView";‘ in your addRow action at the end. where 'myView' is the name of the xhtml page the table is in. this will instruct jsf to create a new view instead of taking the current one. – fischermatte Apr 05 '12 at 15:57
  • Your solution works fine, but not for me at the moment. I've a backing bean view scoped, which have addRow() and arraylist for element of datatable and a backing bean session scoped for calculate first element. In first backing bean, I use a temp variable for create new row (it's create with more step and then it's saved into a db), and if I return new view in addRow(), I lost temp variable...mmm... – 3vi Apr 06 '12 at 08:25
  • it seems there is another way, but i couldn't try it yet. There is a client side option to set the current page. See [here](http://forum.primefaces.org/viewtopic.php?f=3&t=16644). You have to add something like ‛ – fischermatte Apr 07 '12 at 21:25
0

You could avoid the explicit ID in your code by using bindings:

xhtml:

<p:dataTable var="webTemplate" id="templateTable" widgetVar="tbl1" binding="#{calculatePageTable.dataTable" />

bean:

public class CalculatePageTable {
private DataTable dataTable;

public DataTable getDataTable() {
    return dataTable;
}

public void setDataTable(DataTable dataTable) {
    this.dataTable = dataTable;
}

/* See Teg's answer */
public void setPageDataTable() {
    int first = 1;
    if (dataTable.getRowCount() % ROWS_DATATABLE == 0) {
        first = (dataTable.getRowCount() - ROWS_DATATABLE);
    }
    else 
    {
        first = (dataTable.getRowCount()/ROWS_DATATABLE)*ROWS_DATATABLE;
    }
    dataTable.setFirst(first);
}
}
schnatterer
  • 7,525
  • 7
  • 61
  • 80
  • 2
    Bindings make you even more problems, mostly serialization issues: http://stackoverflow.com/questions/8392236/jsf-uicomponent-binding-serializable-and-view-scoped – Danubian Sailor Jul 26 '13 at 09:16