ページ切り替えをちゃんとする。

フィルターと並べ替えに気を取られ、すっかりページ処理が疎かになっていた。ソフトウェアブックの時にpagination_links_remoteメソッドを作っているので、それを使って対応してみた。

ヘルパメソッドの定義

app/helpers/application_helper.rb
ヘルパー
module ApplicationHelper
...(途中省略)...
  def pagination_links_remote(paginator, options={}, html_options={})
    name = options[:name] || ActionView::Helpers::PaginationHelper::DEFAULT_OPTIONS[:name]

    pagination_links_each(paginator, options) do |n|
      options[:url][name] = n
      link_to_remote(n.to_s, options, html_options)
    end
  end
...(途中省略)...
  • ActionView::Helpers::PaginationHelper::DEFAULT_OPTIONSのように指定すれば、モジュール定義の階層を作らなくても良いことを知る。以前はこんな風にやっていた...。
module ActionView
module Helpers
module PaginationHelper
  def pagination_links_remote(paginator, options={}, html_options={})
    name = options[:name] || DEFAULT_OPTIONS[:name]
...(以下省略)...

ページ管理のテンプレートファイルを作成

メソッドのオプション指定が長くなり、全体が見づらくなるので、_list_page.rhtmlでページ切り替えリンクを描画することにした。

app/views/csvs/list.rhtml
ビュー(リスト全体の描画)
...(途中省略)...
<%#= link_to '前ページ', { :page => @csv_pages.current.previous } if @csv_pages.current.previous %>
<%#= link_to '次ページ', { :page => @csv_pages.current.next } if @csv_pages.current.next %> 
<%= render :partial => 'list_page' %>
...(途中省略)...
app/views/csvs/_list_page.rhtml
ビュー(リストのページ切り替えリンクを描画)
<div>
<%= link_to_remote "&#8249; 前", 
            :update => "list_update", 
            :submit => "list_params", 
            :url => { :action => 'list_update', 
                      :page => @csv_pages.current.previous } if @csv_pages.current.previous %>
<span id="pagination_links">
<%= (pagination_links_remote @csv_pages, 
            :update => "list_update", 
            :submit => "list_params", 
            :url => {:action => 'list_update'}) || "1" %>
</span>
<%= link_to_remote "次 &#8250;", 
            :update => "list_update", 
            :submit => "list_params", 
            :url => { :action => 'list_update', 
                      :page => @csv_pages.current.next } if @csv_pages.current.next %>
</div>

並び替えとの連動

今の状態は、例えば、2ページ目を表示している時に並べ替えを行うと、1ページ目に戻ってしまう。自分としては、並び替えても現在のページを保持したいので、以下のようにしてみた。

app/views/csvs/_listh.rhtml
ビュー(リストの列タイトルを描画)
  • 並べ替えた時の送信パラメーターに、現在のページ情報:page => params[:page]を追加した。
<tr>
<% for title in @column_titles %>
  <% sort_direction = (params[:sort_field] == title) ? @next_direction : 'sorted' %>
  <th class=<%= sort_direction %> id=<%= title %>>
  <%= link_to_remote Csv.human_attribute_name(title), 
        :update => 'list_update',
        :submit => 'list_params', 
        :url => {:action => 'list_update', 
                 :sort_field => title, :sort_direction => sort_direction, :page => params[:page]}, 
        :loading => "Element.addClassName('#{title}','loading');" %>
  </th>
<% end %>
</tr>
  • それでは、フィルターを実行した時もページ情報を保持するべきか悩んだが、その場合はページの先頭から表示される方が良いと考えた。
    • フィルター実行後は、全体のリスト件数が変化するので、ページ情報を保持することにあまり意味が無い。
    • 検索した結果は、情報の性格が変化しているので、リストの最初から見たいと思うのが自然な気がした。(例えば、Googleで2ページ目を見ていて、さらに絞り込み検索を行った時に、その結果が2ページ目から表示されるのは勘弁して欲しいと思う。その時2ページ目であることを見落としてしまうと、重要な検索結果である1ページ目を見ないことになってしまう...。)

ちなみに、並び替えの時は...

    • 並べ替えでは全体のリスト件数が変化しないので、現在のページは常に保持できる。
    • また、最終ページを見ていて、並び替え順序を反転した時は、最初のページに戻ってしまうとガックリする。順序を反転するのは、今とは別のデータを見たいからなのに、最初のページに戻ってしまっては、再び同じデータを見ることになる。もう一度ページを移動する必要があり、手間になる。