複数のフィルターでさらに絞り込みたい!その3
前回までに、マルチフィルターの基本部分がひとまず完成した。今回は、フィルターの使い勝ってを向上する機能を追加してみた。全ての機能を追加したフィルターの見た目はこんな感じだ。
- 最初の表示はフィルターなしで、こんな感じ。
- フィルター条件は自由に追加、削除できる。
行ごとに削除リンクを作る。
今まで、フィルター条件の追加しか出来なかったので、削除のリンクも作ってみた。これはシンプルな方法で実現できた。
- まず、フィルター条件の1行ごとにid属性を設定しておく。
- 削除リンクはlink_to_functionで作成する。その中で、Element.remove('削除したいid属性')とするだけでOK。ビューだけの処理で削除が完了してしまった。
- app/views/csvs/_list_filter_condition.rhtml
- ビュー(フィルター条件の行)
<li id=<%= "filter_remove#{@filter_count}" %>> <small> <%= link_to_function '削除', "Element.remove('filter_remove#{@filter_count}')" %> </small> ...(途中省略)... </li>
条件の組み合せにAND、ORの選択を可能にする。
今までは、条件を絞り込むフィルターだけであった。時には、条件を広げるフィルターも使いたくなるだろう。これもちょっとした修正で実現可能だ。
- app/views/csvs/_list_filter.rhtml
- ビュー(フィルターの描画)
...(途中省略)... <!--フィルターの実行/解除/削除の行--> <ul> <small> 上記 <%= select_tag :filter_and_or_op, options_for_select([['すべての', 'AND'], ['いずれかの', 'OR']], params[:filter_and_or_op]) %> 条件と一致する <%= submit_to_remote 'csv_filter', 'フィルターを実行', :update => 'list_update', :submit => 'list_params', :url => {:action => 'list_update'} %> ...(途中省略)... </small> </ul>
- app/controllers/csvs_controller.rb
- コントローラー
...(途中省略)... def set_pagination # :conditionsの設定 filter = params[:filter] || {"0"=>{:column=>@column_titles[0], :item=>"", :id=>20}} sqls = [] filter.each {|c, f| sqls << Filtersql.human_compair_sql(f[:column], f[:item], f[:id])} @conditions = sqls.join(params[:filter_and_or_op]) ...(途中省略)...
フィルターを一時的に解除する。
もしかしたら便利かもしれないと思い、クリックするとフィルター条件はそのままに、一時的にフィルターを解除するリンクも作ってみた。
- app/views/csvs/_list_filter.rhtml
- ビュー(フィルターの描画)
- パラメーターを送信する範囲に、フィルター条件を含めないようにした。それ以外は「フィルターを実行」と同じだ。
...(途中省略)... <%= link_to_remote 'フィルターを一時的に解除', :update => 'list_update', :submit => 'no_filter_params', :url => {:action => 'list_update'} %> ...(途中省略)...
- app/views/csvs/list.rhtml
- ビュー(リスト表示全体の描画)
- id="no_filter_params"は、並べ替え条件を維持するパラメーターの範囲に設定した。
<% if controller.action_name == 'list' %> <h1>CSVリスト</h1> <div id="list_params"> <%= render :partial => 'list_filter' %> <div id="list_update"> <% end %> <!----以上listアクションの時だけ描画----list_updateはこれ以下を描画する------------------> <div id="no_filter_params"> <%# [フィルタを解除]をクリックすると、id="no_filter_params"の範囲だけ送信される。 %> <%# 並び替え条件を維持するため。 %> <%= hidden_field_tag(:sort_field, params[:sort_field]) || 'id' %> <%= hidden_field_tag(:sort_direction, params[:sort_direction]) %> </div> ...(途中省略)...
全てのフィルター条件を削除する。
フィルター条件がたくさんある時、1行ごとに削除するのは面倒なので、フィルター条件を全て削除するリンクも作成した。
- 更新する部分は、レイアウトも含めたページ全体。
- パラメーターは並べ替え条件を維持する範囲だけ送信。
- delete_all_filterアクションを新規作成して、その中でlistアクションへリダイレクトする。
- app/views/csvs/_list_filter.rhtml
- ビュー(フィルターの描画)
<%= link_to_remote '全てのフィルター条件を削除', :update => 'layout_update', :submit => 'no_filter_params', :url => {:action => 'delete_all_filter'} %>
- app/views/layouts/csvs.rhtml
- ビュー(レイアウトファイル)
- 以下のようにレイアウトファイル全体にid="layout_update"属性を設定した。これで、ajax更新なんだけど、listアクションの結果がそのまま描画されると思う。
- もしかしたら、上記リンクをクリックするごとに、divダグがネスト(入れ子、<div><div>...のような状態)されていくかもしれない...。(でも、追加と削除を10回くらい繰り返して問題なかったのでこのままにした。)
<div id="layout_update"> ...(途中省略)... </div>
- app/controllers/csvs_controller.rb
- コントローラー
- 並び替え維持のパラメーターと共にリストアクションへリダイレクトしているだけ。
...(途中省略)... def delete_all_filter redirect_to :action => 'list', :sort_field => params[:sort_field], :sort_direction => params[:sort_direction] end ...(途中省略)...
以上で、マルチフィルターはひとまず完成だ!