What about pagination? (Part 2)
The list we wrote yesterday was just a basic example (we finished with tag 0.3). Today we’re gonna paginate the list using the plugin will_paginate.
That serves a couple of purposes:
- limiting the amount of items will help keeping the UI clean
- using will_paginate proofs that helpers in widgets are just like helpers in controllers
- switching to AJAX pagination will touch Apotomo’s simple event handling
1Limiting the item list means limiting the #find operation in our list widget.
app/cells/item_list.rb
class ItemList < Apotomo::StatefulWidget def display @items = Todo.paginate :page => param(:page), :per_page => 10, :order => 'created_at DESC' render end end
That’s dead simple, we just exchanged #find with #paginate. Accessing request parameters can happen with params[], however, in widgets it’s a good practice to stick to #param.
The later prevents you from accessing parameters not bound to your widget.
2 Obviously we need to fix our view as well, as pagination only makes sense when we got buttons to switch pages.
app/cells/item_list/display.html.haml
%h3 Things
%p
= page_entries_info @items
%ul
- @items.each do |item|
%li
= item.text
= will_paginate @items
When viewing our page, we got a basic paging list, clicking a page button issues a new request.
3That works (tag 0.4), but it’s not the concept behind widgets. Widgets usually want to update via AJAX to save load time and to assure proper encapsulation.
Why should we reload the whole page for updating a single list? That’s overhead!
Keeping that in our collective mind we should add ajaxed buttons.
4Unfortunately will_paginate doesn’t provide a simple way to change the rendering of links (what about some block that’d define the link markup, mislav?) so we’re goin’ that way by foot.
app/cells/item_list/display.html.haml
1 2 3 4 5 6 7 8 9 10 11 | %h3 Things
%p
= page_entries_info @items
%ul
- @items.each do |item|
%li
= item.text
- (1..@items.total_pages).each do |page|
= link_to_event "|#{page}| ", :paginate, :page => page |
We still use the handy #page_entries_info in line 3. To generate the page list we iterate through all available pages (line 10) calling a yet fameless method #link_to_event.

5 The small helper method creates linked page numbers (|1| |2|). When clicking, nothing happens.
Well, you just fired an event! Looking at firebug’s XHTTP tracking, a :paginate event is triggered in the 'dashboard_list'. That’s our baby!
6Alright, so let’s handle this event. In Apotomo, triggered events can be observed, maybe we should try that.
1 2 3 4 5 6 7 8 9 | class ItemList < Apotomo::StatefulWidget def display respond_to_event :paginate, :with => :display @items = Todo.paginate :page => param(:page), :per_page => 10, :order => 'created_at DESC' render end end |
Another apotomo’ed method, #respond_to_event, instructs our list to run the #display state again when it encounters the :paginate event (line 3).
After clicking a page link the updated list appears instantaneously. At the right place. Suuuperfast. Via AJAX. That means:
- the
:paginateevent is triggered - it’s catched by our list widget using
#respond_to_event - the list invokes the
#displaymethod again - the new content replaces the old content, automatically
Cool.
But there’s more.
In the next lessons we’ll polish our list view and add another widget for posting new items. Hope to see you, guys! COMMENT.

March 31st, 2010 at 11:52 am
A peek at the source shows that link_to_event returns <a href=”#” onclick=”new Ajax.Request(… Thinking of Rails 3, do you plan to make this unobtrusive in the future?
March 31st, 2010 at 6:09 pm
hey svoop!
wait for the next lesson, promised!
thanks for your question!!!