0

i am looking for a plain-jsf-solution to handle bookmarkable, parameterbased datatable-pagination.

actually i am using an ajax-approach and a cookie to store the active page. when the user hits F5 or clicks a link in a datatable-row and then returns with "browser-back", i check the cookie to show the last active page.

<h:commandLink value="Next Page">
    <f:ajax listener="#{bean.nextPage}" render="dataTable"/>
</h:commandLink>

@ViewScoped
public class PagerBean  {

   public void nextPage() {
      this.resultList = Products.getNextProducts(getFirstResult(),getMaxResult());
      addCookie("activePage", getActivePage());
   }
}

@ViewScoped
public class ProductBean  {

   @ManagedProperty(value="#{pager}")
   protected PagerBean pager;

   @Postconstruct
   public void init() {

      if (isCookie("activePage"){
         pager.setActivePage(getCookie("activePage"));
      }     
   } 
}

however, i am looking for a bookmarkable solution, so that we can produce links with specific url-parameters, which are also trackable by browser back/forward-button.

http://foo.com/products?page=1
http://foo.com/products?page=2
http://foo.com/products?page=3


<h:link  outcome="/pages/markets/products">                 
   <f:param name="page" value="#{bean.pager.activePage}"/>
</h:link>


@ViewScoped
public class ProductBean  {

   @ManagedProperty(value="#{pager}")
   protected PagerBean pager;

   @Postconstruct
   public void init() {
      final String page = Faces.getRequestParameter("page");
      if (null != page){
         //load next entries          
      }
   }
}

my only problem is, that with this version, the ViewScoped ProductBean gets newly created on every pagination-action. i think, as the view is not changing, the bean should not be re-created. what is the right approach to get lucky?

Steve
  • 384
  • 1
  • 7
  • 17

1 Answers1

0

found a non-primefaces-solution using h:commandLink and HTML5 History API.

on every pagination-action the current pagenumber is stored in the history. when user navigates, the pagenumber will be restored from history and ajax-submitted again.

<h:commandLink value="Next Page">
    <f:ajax listener="#{bean.nextPage}" render="dataTable" onevent="pushState"/>
</h:commandLink>

<h:inputText id="current" value="#{bean.pager.activePage}"/>

<h:commandLink value="Previous Page">
    <f:ajax listener="#{bean.prevPage}" render="dataTable" onevent="pushState"/>
</h:commandLink>

<!--hidden action fired when user navigates in history-->
<h:commandLink styleClass="hidden" id="hiddenLink">
    <f:ajax execute="current" listener="#{bean.jumpToPage}" render="dataTable" />
</h:commandLink>

JS:

$(window).on('popstate', function(event) {

    var pageInHistory = event.originalEvent.state;      
    if (null == pageInHistory){
        pageInHistory = 1;
    }
    //set page number from history
    $('#current').val(pageInHistory);
    //trigger ajax-submit
    $('#hiddenLink').trigger('click');

});

pushState = function (data){
  switch (data.status) {      
    case "success": {
       var currentPage = $('#current').val();
       history.pushState(currentPage, null, "?page=" + currentPage);    
    }
 }

Bean

@ViewScoped
public class PagerBean  {

   private int activePage;

   public void jumpToPage() {
      //load data for activePage   
   } 

   //...
}
Steve
  • 384
  • 1
  • 7
  • 17