Question about pagination


#1

Hi!

I’ve got a list of project on the main page and if one of them is
selected i render a partial using ajax with data of selected project.

How to create links to next/previous project using pagination?


#2

use the pagination_links.

 @customer_pages, @customers =  paginate(:customers, options_hash)

then in your view you have access to @customer_pages which is a
paginator, and therefore can do things like this:

<% paginator = @customer_pages %>

<%= unless paginator.current == paginator.first then link_to
(“first”, :page => paginator.first)
else ‘first’ end %>

<%= if paginator.current.previous then link_to(“prev”, :page =>
paginator.current.previous)
else ‘prev’ end %>

<%= if paginator.current.next then link_to(“next”, :page =>
paginator.current.next)
else ‘next’ end %>

<%= unless paginator.current == paginator.last then link_to
(“last”, :page => paginator.last)
else ‘last’ end %>

| <%= pagination_links @customer_pages, {:window_size => 5} %>

It gets even more fun if you’re passing a hash of values for
conditions (like search filtering, or pop-up-value filtering… then
you need to build an options hash, too… and you end up like this:

<% # options hash for pagination links
opt_hash = { :search_box => @search_box }
opt_hash[:is_something] = @is_something unless(@is_something.empty?)
# etc…
%>

<% params_hash = opt_hash # grab the params hash before the :page key
of it has been set - for the pagination links down below %>

<%= unless paginator.current == paginator.first then
opt_hash[:page] = paginator.first
link_to(“first”, opt_hash)
else ‘first’ end %>

<%= if paginator.current.previous then
opt_hash[:page] = paginator.current.previous
link_to(“prev”, opt_hash)
else ‘prev’ end %>

<%= if paginator.current.next then
opt_hash[:page] = paginator.current.next
link_to(“next”, opt_hash)
else ‘next’ end %>

<%= unless paginator.current == paginator.last then
opt_hash[:page] = paginator.last
link_to(“last”, opt_hash)
else ‘last’ end %>

| <%= pagination_links @customer_pages, {:window_size => 5, :params
=> params_hash} %>

Julian.


#3

Thanks for explaining this!

But i still have a problem.
I have a list of projects. If one is selected i pass its id to ‘show’
action.
It looks like this:

@project = Project.find(params[:id])
@project_pages, @projects = paginate :projects, :per_page => 1
render :partial => “project”, :locals => {:project => @project,
:project_pages => @project_pages}

How to somehow connect my @project with @project_pages paginator, so it
will know which project is currently displayed and which is
next/previous? If i try to display any link i.e. like this:

<%= link_to(“previous project”, :page =>
@project_pages.current.previous) if @project_pages.current.previous %>

it is not displayed.

Am i passing the paginator wrongly to my partial?


#4

Well it doesn’t work correctly…

My list of projects in the menu is sorted by date. So when the user
chooses one and then selects next projects using ‘next project’ link
he/she can expect to get next project from the list.

But because i use position column i get next project from the table, not
from the list.

I checked in api and in paginate method there’s no option to set current
page, and in Paginator.new there’s no option to set conditions. And even
if could set conditions and current page, i still know only selected
project position in the table, not in the sorted list.

So how to do it?


#5

I’ve managed to do this, but maybe someone knows an easier way.

I added acts_as_list to my Project model, which allowed me to get model
instance position and set :page property of paginator correctly.

BTW. Does someone know how to write mysql procedure to update all values
in ‘position’ column automatically?