0

This may have been covered somewhere but I'm having trouble forming the question for search engine and no goods leads thus far.

I'm working on a page that acts as entity view. Lots of results come from database and only a handful are displayed at a time. So you can imagine that I want to build a list of links that take user to another page of entities. This is all my code - no PrimeFaces or any other front-end nifty pagination solutions. At least for now.

To the code:

@Named
@SessionScoped
public class ArticleIndexBean {
    List<Article> articleList=new ArrayList<>();
    List<Article> articleSubList=new ArrayList<>();

@PostConstruct
public void loadScreenSupport() {
    search();
    toEntityPage(1);
    }

protected void search() {
        // this method sets articleList which is the full list fetched from the database
    }

public void toEntityPage(int pageNumber) {
       // this method sets articleSubList which is a subset of articleList 
}

Each page link needs to call toEntiyPage(n). I am aware of commandLink but I want to avoid a POST request. Also, the bean is currently session scoped and I will try to make it conversation scoped later. It will certainly NOT be request scoped, as I don't want to do a full db search each time a user wants to jump to another page. So @PostConstruct won't help, either.

So with a menu like this: 1 * 2 * 3 * 4 * 5 how do I code an outputLink or any other type of link that will call my ArticleIndexBean.toEntityPage(int) via a GET request?

Solution

Based on input from Laurent, I added a currentEntityPageNumber property and a toCurrentEntityPage() method to my bean. The toCurrentEntityPage() simply calls toEntityPage(getCurrentEntityPageNumber()).

<html lang="en"
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  >

<f:metadata>
    <f:viewParam name="pn" value="#{articleIndexBean.currentEntityPageNumber}" />
    <f:event type="preRenderView" listener="#{articleIndexBean.toCurrentEntityPage()}" />
</f:metadata>

<c:forEach var="pageNumber" begin="1" end="${articleIndexBean.getEntityPageCount()}">   
                <h:outputLink value="ar_index.xhtml">
                        <h:outputText value="${pageNumber}" />
                        <f:param name="pn" value="${pageNumber}" />
                </h:outputLink>
    </c:forEach>

It would certainly be better if we could call toEntityPage(pageNumber) directly but this works fine.

jacekn
  • 1,521
  • 5
  • 29
  • 50

1 Answers1

0

Assuming you are using JSF 2.2, you could use the viewParam to retrieve the page in the GET parameters and viewAction to call a method before the rendering (actually called in the INVOKE_APPLICATION phase by default).

Facelets:

<f:metadata>
    <f:viewParam name="page" value="#{articleIndexBean.entityPage}" />
    <f:viewAction action="#{articleIndexBean.loadScreenSupport}" />
</f:metadata>

If you are using JSF 2.0 or JSF 2.1, then you have to replace viewAction by:

<f:event type="preRenderView" listener="#{articleIndexBean.loadScreenSupport}" />

Java:

@Named
@SessionScoped
public class ArticleIndexBean {
    List<Article> articleList=new ArrayList<>();
    List<Article> articleSubList=new ArrayList<>();

    int pageNumber = 1; // by default first page

    public void loadScreenSupport() {
        search();
        toEntityPage(pageNumber);
    }

    public int getPageNumber() {
        return pageNumber;
    }

    public void setPageNumber(int pageNumber) {
        this.pageNumber = pageNumber;
    }

    protected void search() {
        // this method sets articleList which is the full list fetched from the database
    }

    public void toEntityPage(int pageNumber) {
       // this method sets articleSubList which is a subset of articleList 
    }
}

The link to the page is then easy:

<h:outputLink value="resultPage.xhtml">
    <h:outputText value="2" />
    <f:param name="page" value="2" />
</h:outputLink>

Reference:

Community
  • 1
  • 1
LaurentG
  • 11,128
  • 9
  • 51
  • 66
  • I'm using TomEE 1.6 so I'm stuck with myfaces-api-2.1.13.jar. Following your solution for faces 2.1 or earlier, I'm running into trouble with ``. How should I define `f` namespace? – jacekn Feb 15 '14 at 17:42
  • My code examples are only a small fragment of what I'm doing. The pagination is actually implemented in a another view. For some reason, I'm running into issues there and thought those were related to f:metadata declaration. Now, I know they're not. Your solution works fine. Thanks Laurent. – jacekn Feb 15 '14 at 21:40