Tuesday Aug 04, 2009

TOTD #89: How to add pagination to an Apache Wicket application


TOTD #86 explained how to get started with deploying a Apache Wicket application on GlassFish. This Tip Of The Day (TOTD) will show how to add pagination to your Wicket application.

The blog entry "JPA/Hibernate and Wicket Repeating Views with Netbeans" Part 1 and 2 explain in detail how to create a CRUD application using NetBeans, JPA, Hibernate and Wicket. This blog uses the data created in TOTD #38 for the database table.
  1. After creating the JPA Controller, adding the IDataProvider and DataView implementations and hooking together, the application is available at "http://localhost:8080/helloworld" and looks like:



    As noticed in the output, all the states are listed in one page. The HTML markup looks like:

    <html>
        <head>
            <title>Wicket Quickstart Archetype Homepage</title>
        </head>
        <body>
            <strong>Wicket Quickstart Archetype Homepage</strong>
            <br/><br/>
            <span wicket:id="message">message will be here</span>
            <table>
                <tr>
                    <th>ID</th>
                    <th>Abbreviation</th>
                    <th>Name</th>
                </tr>
                <tr wicket:id="rows">
                    <td><span wicket:id="id">ID</span></td>
                    <td><span wicket:id="abbrev">Abbreviation</span></td>
                    <td><span wicket:id="name">Name</span></td>
                </tr>
            </table>

        </body>
    </html>

    The backing POJO looks like:

    package org.glassfish.samples;

    import java.util.Iterator;
    import org.apache.wicket.PageParameters;
    import org.apache.wicket.markup.html.basic.Label;
    import org.apache.wicket.markup.html.WebPage;
    import org.apache.wicket.markup.repeater.Item;
    import org.apache.wicket.markup.repeater.data.DataView;
    import org.apache.wicket.markup.repeater.data.IDataProvider;
    import org.apache.wicket.model.CompoundPropertyModel;
    import org.apache.wicket.model.IModel;
    import org.apache.wicket.model.LoadableDetachableModel;
    import org.glassfish.samples.controller.StatesJpaController;
    import org.glassfish.samples.model.States;

    /\*\*
     \* Homepage
     \*/
    public class HomePage extends WebPage {

        private static final long serialVersionUID = 1L;

        // TODO Add any page properties or variables here

        /\*\*
         \* Constructor that is invoked when page is invoked without a session.
         \*
         \* @param parameters
         \*            Page parameters
         \*/
        public HomePage(final PageParameters parameters) {

            // Add the simplest type of label
            add(new Label("message", "If you see this message wicket is properly configured and running"));

            // TODO Add your page's components here

                    // create a Data Provider
            IDataProvider statesProvider = new IDataProvider() {
                public Iterator iterator(int first, int count) {
                    StatesJpaController sc = new StatesJpaController();
                    return sc.findStatesEntities(count, first).iterator();
                }

                public int size() {
                    StatesJpaController sc = new StatesJpaController();
                    return sc.getStatesCount();
                }

                public IModel model(final Object object) {
                    return new LoadableDetachableModel() {
                        @Override
                        protected States load() {
                            return (States)object;
                        }
                    };
                }

                public void detach() {
                }
            };

            // TODO Add your page's components here

            DataView dataView = new DataView("rows", statesProvider) {

                @Override
                protected void populateItem(Item item) {
                    States state = (States)item.getModelObject();
                    item.setModel(new CompoundPropertyModel(state));
                    item.add(new Label("id"));
                    item.add(new Label("abbrev"));
                    item.add(new Label("name"));
                }
            };

            add(dataView);
        }
    }

    and "persistence.xml" looks like:

    <?xml version="1.0" encoding="UTF-8"?>
    <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
      <persistence-unit name="helloworld" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <class>org.glassfish.samples.model.States</class>
        <properties>
          <property name="hibernate.connection.username" value="app"/>
          <property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.ClientDriver"/>
          <property name="hibernate.connection.password" value="app"/>
          <property name="hibernate.connection.url" value="jdbc:derby://localhost:1527/sample"/>
        </properties>
      </persistence-unit>
    </persistence>
  2. Lets add pagination to this simple sample.
    1. In the POJO, change DataView constructor so that it looks like:

              DataView dataView = new DataView("rows", statesProvider, 5)

      where "5" is the number of entries displayed per page. Alternatively you can also set the number of items per page by invoking:

      dataView.setItemsPerPage(5);

    2. In the HTML page, add the following right after "<table/>":

      <span wicket:id="pager">message will be here</span><br>

      as the last line. This is the placeholder for pagination controls.
    3. In the POJO, add the following:

              PagingNavigator pager = new PagingNavigator("pager", dataView);
              add(pager);

      right after "add(dateView);".

      The output now looks like:



      and clicking on ">" shows:



      And finally clicking on ">>" shows



      The information is now nicely split amongst multiple pages.
So just adding a pagination controls placeholder in the HTML and a corresponding configuration in DataView (in the backing POJO) did the trick for us.

Please leave suggestions on other TOTD (Tip Of The Day) that you'd like to see. A complete archive of all the tips is available here.

Technorati: wicket glassfish pagination

Sunday Aug 02, 2009

TOTD #88: How add pagination to Rails - will_paginate


This Tip Of The Day (TOTD) explains how to add pagination to your Rails application.
  1. Create a simple Rails scaffold as:

    ~/samples/jruby >~/tools/jruby/bin/jruby -S rails paginate
    ~/samples/jruby/paginate >~/tools/jruby/bin/jruby script/generate scaffold book title:string author:string
    ~/samples/jruby/paginate >sed s/'adapter: sqlite3'/'adapter: jdbcsqlite3'/ <config/database.yml >config/database.yml.new
    ~/samples/jruby/paginate >mv config/database.yml.new config/database.yml
    ~/samples/jruby/paginate >~/tools/jruby/bin/jruby -S rake db:migrate

  2. Edit "test/fixtures/books.yml" and specify the content as:

    # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html

    one:
      title: Ultramarathon Man Confessions of an All-Night Runner
      author: Dean Karnazes

    two:
      title: My Life on the Run
      author: Bart Yasso

    three:
      title: 50/50 Secrets I Learned Running 50 Marathons in 50 Days
      author: Dean Karnazes

    four:
      title: Born to Run
      author: Christopher Mcdougall

    five:
      title: Four Months to a Four-hour Marathon
      author: Dave Kuehls

    six:
      title:  Galloway's Book on Running
      author: Jeff Galloway

    seven:
      title: Marathoning for Mortals
      author: John Bingham and Jenny Hadfield

    eight:
      title:  Marathon You Can Do It!
      author: Jeff Galloway

    nine:
      title: Marathon The Ultimate Training Guide
      author: Hal Higdon

    ten:
      title: Running for Mortals
      author: John Bingham and Jenny Hadfield

    and load the fixtures as:

    ~/samples/jruby/paginate >~/tools/jruby/bin/jruby -S rake db:fixtures:load
    (in /Users/arungupta/samples/jruby/paginate)

  3. Run the application as:

    ~/samples/jruby/paginate >~/tools/jruby/bin/jruby -S glassfish -l
    Starting GlassFish server at: 129.145.132.8:3000 in development environment...
    Writing log messages to: /Users/arungupta/samples/jruby/paginate/log/development.log.

    . . .

    Jul 29, 2009 2:06:44 PM com.sun.grizzly.scripting.pool.DynamicPool$1 run
    INFO: New instance created in 7,488 milliseconds

    The application is accessible at "http://localhost:3000/books" and looks like:



    The page shows 10 rows, all in one page.
  4. Lets add pagination to this simple sample.
    1. Install will_paginate gem as:

      /tools/jruby >./bin/jruby -S gem install will_paginate
      JRuby limited openssl loaded. gem install jruby-openssl for full support.
      http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL
      Successfully installed will_paginate-2.2.2
      1 gem installed
      Installing ri documentation for will_paginate-2.2.2...
      Installing RDoc documentation for will_paginate-2.2.2...

      There are other methods of installation as well.
    2. Edit "config/environment.rb" and add

      require "will_paginate"

      as the last line.
    3. Edit the "index" action in "app/controllers/books_controller.rb" as:

      @books = Book.paginate(:page => params[:page], :per_page => 5)
      #@books = Book.all

      ":per_page" specifies the number of items to be displayed in each page.
    4. In "app/views/books/index.html.erb", add:

      <%= will_paginate @books %>

      right after "</table>".

      The output now looks like:



      and clicking on "Next" shows:



      The information is nicely split amongst 2 pages.
An important point to remember is that will_paginate only adds pagination to your Rails app. You are still required to display all the values.

But essentially replacing "@books = Book.all" with "@books = Book.paginate(:page => params[:page], :per_page => 5)" in the Controller and adding
"<%= will_paginate @books %>" did the trick for us.

Clean and simple!

Please leave suggestions on other TOTD (Tip Of The Day) that you'd like to see. A complete archive of all the tips is available here.

Technorati: jruby rubyonrails glassfish pagination will_paginate
About

profile image
Arun Gupta is a technology enthusiast, a passionate runner, author, and a community guy who works for Oracle Corp.


Java EE 7 Samples

Stay Connected

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today