Pagination in Rails and how to implement go to page functionality
Customization of will_paginate
gem
On web pages, sometimes you have many rows of information, lets say: a list of users on the system. In that situation having all the users listed on the same page is not very usable. For that we use pagination that allow us to divide the rows on several pages and order them based on date, name or other field.
On Rails applications one of the most common used gems is will_paginate
. This gem is very easy to implement but have some limitations. Some of the limitations that we found are the ability to use Ajax to only render the changed rows of the data and how to go to an specific page functionality. Solving these two limitations is the purpose of this post.
How to use will_paginate
Like most gems needed in a project, we add it to the Gemfile:
## Gemfile for Rails 3+gem 'will_paginate', '~> 3.1.1'
gem 'will_paginate-bootstrap'
#this is needed to add bootsrap style to pagination
There are important parameters to setup to manage the pagination:
per_page
: number of items to display on each page.page
: the page that will be displayed initially when we load the page.
Example: Item.paginate page: params[:page], per_page: 10
In the view that we require this functionality, we add the navigation bar:
#erb files
<%= will_paginate @items , renderer: RemoteLinkPagination::LinkRenderer %>-# haml files
= will_paginate @items, renderer: RemoteLinkPagination::LinkRenderer# On both cases we are using a custom renderer implemented to
# satisfy our needs. Keep reading to understand why
where @items
has all the information that will be displayed as rows in your page.
Also take into account that we are using an overridden version of LinkRenderer, it will helps to:
a) Allow will_paginate
to use Ajax, and
b) Be able to generate the go to page functionality.
If you use bootstrap in your Rails application you will have some nice styles applied to the navigation bar. The navigation bar has several buttons that allow you to go to the page you want and has an ellipsis to denote middle pages that looks like this:
Ajax functionality
Since we are using rails and the default configuration is to capture all data-remote links, we just need to include data-remote=true
to the links generated by will_paginate
. To accomplish that we should override thelink
method with the following code:
def link(text, target, attributes = {})
attributes['data-remote'] = true
super
end
After that we should create a .js
view that renders the data that we want to replace in the general view with something like:
Go to page functionality
When the number of pages is too high, navigation buttons only permit to go to pages that are numbered in them. But, sometimes we want to go to a specific page, lets say in the above example page 211. To solve this, we implemented the following functionality:
When clicking on the ellipsis, a textbox will be displayed to enter the page number we want to go.
Implementation
First we need to create a file under the lib
directory called remote_link_pagination.rb
and create a module called RemoteLinkPagination
. Then you need to overwrite the gap
function to add a data identificator:
After that we need to add some javascript code to set a new page parameter. In this case, add add a file called paginator.js
under app/assets/javascripts
folder and write the following code:
We also need to add inconfig/application.rb
the following:
config.autoload_paths << Rails.root.join(‘lib’)
inside application class.
And voilà, the final result should look something like this:
Final thoughts
I hope this post was useful for you and you implement this solution on your Rails application. Here is a sample Rails application where this functionality is implemented. You can download a complete example from this Github repository:
If you have any comments or questions, please leave it behind or contact me at:
Eng: Milber Champutiz
Email: milber.ch@gmail.com