並び替えの処理中にクルクル回るイージケーターを表示する。
結構、憧れていたのだ...。ajax_scaffoldで、処理中にクルクル回るイージケーターに。
最小限の機能で並び替えを実装
まずは必要最小限の機能で、並び替えを実装してみた。まだ、並び替えの方向や、対象列の強調表示などのフィードバックは何もなし。
- 列タイトルのリンクをクリックすると、その列をキーに並び替える。
- 同じ列タイトルを繰り返しクリックすると、並び替えの方向を反転する。
<%# ---------- app/views/csvs/_listh.rhtml ---------- %> <tr> <% for title in @column_titles %> <% sort_direction = (params[:sort_field] == title) ? @next_direction : 'sorted' %> <th> <%= link_to Csv.human_attribute_name(title), :sort_field => title, :sort_direction => sort_direction %> </th> <% end %> </tr>
# ---------- app/controllers/csvs_controller.rb ---------- def list @next_direction = (params[:sort_direction] == 'asc') ? 'desc' : 'asc' order = "#{params[:sort_field] || 'id'} #{@next_direction}" @csv_pages, @csvs = paginate :csvs, :per_page => 10, :order => order end
フィードバックが無いと、状況がつかめず、実行した操作に対する不安が残る...。
ajaxで並び替え
処理中にイージケーターを回すためには、ajaxの利用が必要と考え、link_to_remoteで同じ処理を実現してみる。
- update => 'list_update'は、ajax更新する部分。<div id="list_update">タグで、レイアウトファイル全体を指定した。
<%# ---------- app/views/csvs/_listh.rhtml ---------- %> <tr> <% for title in @column_titles %> <% sort_direction = (params[:sort_field] == title) ? @next_direction : 'sorted' %> <th> <%= link_to_remote Csv.human_attribute_name(title), :update => 'list_update', :url => {:sort_field => title, :sort_direction => sort_direction} %> </th> <% end %> </tr>
- ajaxでは描画ファイルを明示的に指定する必要があるので、render :action => 'list'を追加した。
# ---------- app/controllers/csvs_controller.rb ---------- def list @next_direction = (params[:sort_direction] == 'asc') ? 'desc' : 'asc' order = "#{params[:sort_field] || 'id'} #{@next_direction}" @csv_pages, @csvs = paginate :csvs, :per_page => 10, :order => order render :action => 'list' end
- <div id="list_update">タグで囲まれた部分が、ajaxで更新される範囲。つまり、ページ全体にしてしまったのだ。
- 最初、うっかり<%= javascript_include_tag :defaults %>を忘れていて、思った通りに動作せず悩んでしまった。ajaxを利用する時には必須です。
<%# ---------- app/views/layouts/csvs.rhtml ---------- %> <div id="list_update"> <html> <head> <title>Csvs: <%= controller.action_name %></title> <%= stylesheet_link_tag 'scaffold' %> <%= stylesheet_link_tag 'list_o_matic' %> <%= javascript_include_tag :defaults %> </head> <body> <%= render :partial=>"layouts/menu2" %> <%= render :partial=>"layouts/flash" %> <%= yield %> </body> </html> </div>
以上で、ajaxによるページ更新になった。並び替えのリンクをクリックしても、URLは変化しなくなった。
処理中にクルクル回るイージケーターを表示
ajax_scaffoldの処理方法そのままだが、自分なりに理解してやってみた。
- ajax_scaffoldを利用していると、public/images/indicator.gifがインストールされている。これがクルクル回るイージケーターになる。gifアニメーションの画像だ。試しにブラウザにドラッグしてみると、イージケーターがクルクル回っている画像が表示される。
- 処理中にイージケーターを表示するために、link_to_remoteの:loading => オプションを指定した。ここで指定したことは、処理の間だけ実行されるようだ。処理が終わると元の状態に戻る。
- :loading => オプションでは、"Element.addClassName('#{title}','loading');"というJavaScriptを指定した。id="#{title}"のタグに、class="loading"を追加する処理のようだ。
- つまり、<th id=<%= title %>>タグは、並び替えの処理中だけ<th id=<%= title %> class="loading">という状態になる。
<%# ---------- app/views/csvs/_listh.rhtml ---------- %> <tr> <% for title in @column_titles %> <% sort_direction = (params[:sort_field] == title) ? @next_direction : 'sorted' %> <th id=<%= title %>> <%= link_to_remote Csv.human_attribute_name(title), :update => 'list_update', :url => {:sort_field => title, :sort_direction => sort_direction}, :loading => "Element.addClassName('#{title}','loading');" %> </th> <% end %> </tr>
- スタイルシートでは、<th id=<%= title %> class="loading">タグに対する表示設定を行う。一番下のブロックで、処理中のテーブルヘッダーの背景画像に、indicator.gifを指定している。
background: lavender url(../images/indicator.gif) right 50% no-repeat;
- この指定で、class="loading"の状態の時だけ、indicator.gifを背景画像として表示してくれるのだ。
th { text-align: left; } th a { font: bold 11px verdana, sans-serif; display: block; } th a, th a:visited { color: #999; padding: 2px 20px 2px 2px; } th a:hover { background-color: #000; color: #fff; } th.loading a, th.loading a:hover { background: lavender url(../images/indicator.gif) right 50% no-repeat; }
以上で、並び替えの処理中には、イージケーターがクルクル回ってくれる!
並び替え方向の矢印も背景画像で
- その後、並べ替え方向を示す上下の矢印も表示するようにしてみた。
>タグに、class=<%= sort_direction %> を追加しただけ。 <%# ---------- app/views/csvs/_listh.rhtml ---------- %> <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', :url => {:sort_field => title, :sort_direction => sort_direction}, :loading => "Element.addClassName('#{title}','loading');" %> </th> <% end %> </tr>
- 矢印を背景画像として表示するスタイルシートを設定すると、並び替えの方向が表示されるようになる。
th.asc a { background: lavender url(../images/arrow_up.gif) right 50% no-repeat; color: #000; } th.asc a:hover { background: #000 url(../images/arrow_up.gif) right 50% no-repeat; color: #fff; } th.desc a { background: lavender url(../images/arrow_down.gif) right 50% no-repeat; color: #000; } th.desc a:hover { background: #000 url(../images/arrow_down.gif) right 50% no-repeat; color: #fff; }