2

I'm developing a web search engine and it is all set in the C/Java programming, now what's left is the website, and I'm quite a newbie in this area. So, I have the results page, the results are displayed inside a div, and this div shows the content of a list, like this.

<div id="results">
  <ui:repeat value="searchBean.shownResults" var="node">
    node.website
    node.resume
    node.link
    etc...
  </ui:repeat>
</div>

And then I have a div to display the page roller, it is pretty much like the one you'll find if you google something and scroll down the page. I made a bean that controls what number should be displayed, so if the user clicks 10 for example, the pages displayed will be "5 6 7 8 9 10 11 12 13 14", instead of "1 2 3 4 5 6 7 8 9 10".

What I don't know how to do is to when the user clicks a page link (a number), send this number to me bean, so I can calculate the pages window and then refresh only the div where the results are displayed (and the roller, obviously enough), and the selected page must be unselectable.

Also, I would like to show the page on the url, like this www.searchengine.com/?pg=<page#>.

-- Based on Luiggi Mendoza's answer...

    <h:form>
        <table>
            <tr>
                <ui:repeat id="foo" value="#{footer.list}" var="no">
                    <td>
                        <h:commandLink value="#{no}" action="#{footer.navigate(no)}">
                            <f:ajax  render="@form foo"/>
                        </h:commandLink>
                    </td>
                </ui:repeat>
            </tr>
        </table>
    </h:form>
victor
  • 1,532
  • 1
  • 13
  • 32

1 Answers1

2

I've made a quick test for this (sorry for not implementing the roller in Google fashion, maybe you will ;) ). I use plain JSF in the code.

JSF page:

<div>
    <h:panelGrid id="pnlCurrentData">
        <ui:repeat value="#{pageRollerBean.lstCurrentData}" var="data">
            #{data}
        </ui:repeat>
    </h:panelGrid>
</div>
<h:form id="frmPages">
    <h:panelGrid id="pnlPages">
        <ui:repeat value="#{pageRollerBean.lstPages}" var="i" >
            <div style="display: inline-block; margin-left: 5px; margin-right: 5px">
                <!-- some styling just to see the selected/unselected page -->
                <!-- you can send the page number in the action -->
                <h:commandLink value="#{i}"
                    action="#{pageRollerBean.loadData(i)}"
                    style="#{i eq pageRollerBean.currentPage ? 'color:#FF0000' : 'color:#0000FF'}">
                    <!-- using ajax to update the results and the pages list -->
                    <f:ajax render=":frmPages:pnlPages :pnlCurrentData" />
                </h:commandLink>
            </div>
        </ui:repeat>
    </h:panelGrid>
</h:form>

Managed Bean code:

@ManagedBean
@ViewScoped
public class PageRollerBean {

    //Just to have some data to show for the test
    //for your case, this data should come when the user searches data
    private static List<String> lstData;

    static {
        lstData = new ArrayList<String>();
        for(Integer i = 1; i <= 100; i++) {
            lstData.add(i.toString());
        }
    }

    private List<String> lstCurrentData;
    private static final int totalPages = 10;
    private List<Integer> lstPages;
    private int currentPage;

    public PageRollerBean() {
    }

    @PostConstruct
    public void init() {
        lstPages = new ArrayList<Integer>();
        for(Integer i = 1; i <= totalPages; i++) {
            lstPages.add(i);
        }
        loadData(1);
    }

    //getters and setters...

    public void loadData(int page) {
        //this code explains by itself what it does...
        this.currentPage = page;
        lstCurrentData = lstData.subList((page-1)*10, (page-1)*10 + 10);
    }
}
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • ui:repeat within a h:panelGrid will result in a single column, so I used a
    ..repeat..
    . Can you explain to me this line ""? Since :pnlCurrentData is not inside a form, nor inside the frmPages, I dont undersantad why this works. Also I need to disable the link for current page, if you are in page 7, you cant click 7.
    – victor Feb 25 '13 at 16:48
  • I noticed that ViewScope and SessionScope does not work for me, because if I click on a result link, then click back on my browser, the page roller is reseted, how do I keep the object until the user closes the browser or tab... – victor Feb 25 '13 at 16:56
  • @user1836773 I use `` as UIContainer to refresh the list with results, since this was a sample I only used a single column, but you can generate a whole `` using the ``. Now, you can set the id's of the components you want to render (update) after the ajax request has been finished, so I use `:pnlCurrentData` in order to say *from the main component tree, update the component with ID `pnlCurrentData`*, now for `:frmPages:pnlPages` is *from the main component tree, update the component with ID `pnlPages` that's inside the component with ID `frmPages`*
    – Luiggi Mendoza Feb 25 '13 at 16:58
  • @user1836773 there's nothing wrong with `@ViewScoped` nor `@SessionScoped`, just a HTML misconception: ajax requests don't get saved in browser history, so if you click *back* you will see the page in the way it started. If you want to show the last result, then drop the `` and get a full new result for your page. In order to process the GET parameters with a `@ViewScoped` managed bean, you can check [What can and be used for?](http://stackoverflow.com/q/6377798/1065197) – Luiggi Mendoza Feb 25 '13 at 17:00
  • @user1836773 it's up to you how to define if the items are enabled, disabled, etc. I just used a basic style to show the links and the link that is currently selected (note that this is outside the scope of the question). – Luiggi Mendoza Feb 25 '13 at 17:01
  • I missed the space between :frm:Pages:pnlPages and :pnlCurrentData, sorry about that. Thank you very much for your time. – victor Feb 25 '13 at 17:44
  • @user1836773 don't worry :). By the way, I use `` in order to render the inner `` and use `
    `s to make them appear next to each other.
    – Luiggi Mendoza Feb 25 '13 at 17:46