コードでもカナでも漢字でも検索可能なプルダウンリスト
銀行と支店が連動して、だいぶ使い易くなってきたが、まだまだストレスを感じる。今、検索のキーになっているのはkanaフィールドのみ。ユーザーの中には、よく使う銀行コードは覚えてしまっているからコードで指定したいんだとか、正しい読み方は分からないけど漢字なら知っているというケースもあるだろう。
だからといって、code、kana、name用のtext_fieldを3つ用意するなんていう使い勝手を無視したインターフェースにはしたくない。入力するtext_fieldは一つ、コードでもカナでも漢字でも区別なく検索できることを目指す。
コントローラーの修正
- 検索するのはコントローラーなので、まずは以下のように修正した。
# コントローラー:銀行の検索 def auto_complete_for_bank_kana @phrase = params[:bank][:kana].gsub(/[ ]/,' ').strip.downcase find_options = { :conditions => ["(LOWER(id) LIKE ? OR LOWER(kana) LIKE ? OR LOWER(name) LIKE ?)", "#{@phrase.gsub(/^0+/, '')}", "%#{@phrase}%", "%#{@phrase}%"], :order => "kana ASC", :limit => 10 } @items = Bank.find(:all, find_options) render :partial => 'auto_complete_for_bank_kana' end # コントローラー:支店の検索 def auto_complete_for_branch_kana @phrase = params[:branch][:kana].gsub(/[ ]/,' ').strip.downcase Branch.with_scope(:find=>{:conditions=>[ "bank_id=?", params[:payee_account][:bank_id] ]}) do find_options = { :conditions => ["(LOWER(code) LIKE ? OR LOWER(kana) LIKE ? OR LOWER(name) LIKE ?)", "#{@phrase.gsub(/^0+/, '')}", "%#{@phrase}%", "%#{@phrase}%"], :order => "kana ASC", :limit => 10 } @items = Branch.find(:all, find_options) render :partial => 'auto_complete_for_branch_kana' end end
- 余分なスペースを削除して、検索キーを@phraseに代入しておく。
- 上記キーを元に、:conditionsの部分でフィールドごとの条件を書いてORで繋げた。
- コード検索については「0009」も「9」も同じコードと見做すことにした。("#{@phrase.gsub(/^0+/, '')}")
選択リストのビューを修正
複合的な検索は、上記コントローラーの修正だけで実現できているが、選択リストの見た目にも少し手を加えてみた。
<%# ビュー_auto_complete_for_bank_kana.rhtml %> <ul> <% @items.each do |item| %> <li> <%# 支店情報をクリアするための項目 %> <span connect="payee_account_branch_id"></span> <span connect="branch_kana"></span> <%# 値を設定するための非表示項目 %> <span connect="payee_account_bank_id" style="display:none"><%= item.id %></span> <span connect="bank_kana" style="display:none"><%= fit_digit(item.id, 4) %> <%= item.name %></span> <%# 選択リストに表示する項目 %> <span class="informal" style="margin:2.8em"><%= highlight(item.kana, @phrase) %><br /></span> <span class="informal"><%= fit_digit(item.id, 4) %> <%= highlight(item.name, @phrase) %></span> </li> <% end %> <% if @items.blank? %> <li> <span connect="payee_account_branch_id"></span> <span connect="branch_kana"></span> <span connect="payee_account_bank_id"></span> <span connect="bank_kana"></span> <span class="informal">銀行が見つかりません。</span> </li> <% end %> </ul>
- リストを選択すると、「0001 みずほ銀行」のように表示されるようにした。
- 検索キーと一致したら、カナ、漢字それぞれを強調表示(ハイライト)するようにした。
- 本来は以下のようにしたかったのだが、highlightを使うとその部分がtext_fieldに表示されなかった(謎)ので、仕方なく「値を設定するための非表示項目」と「選択リストに表示する項目」に分けて描画することにした。
<span connect="bank_kana"><%= fit_digit(item.id, 4) %> <%= highlight(item.name, @phrase) %></span>
- 漢字の銀行名の上にカナ表示するようにしてみた。
- fit_digitは、自分で定義した、数値の桁数を揃えるヘルパメソッド。
# ---------- app/helpers/application_helper.rb ---------- module ApplicationHelper # 数値の桁数を揃えた文字列を返す。 # fit_digit(数値, 桁数, 不足する桁を埋める文字) # 例: # fit_digit(1, 4) => "0001" # fit_digit(12, 4, '_') => "__12" def fit_digit(value, digit, str='0') str * (digit - value.to_s.size) + value.to_s rescue value.to_s end
同じように支店のリスト表示も修正する。
<%# ビュー_auto_complete_for_branch_kana.rhtml %> <ul> <% @items.each do |item| %> <li> <%# 値を設定するための非表示項目 %> <span connect="payee_account_branch_id" style="display:none"><%= item.id %></span> <span connect="branch_kana" style="display:none"><%= fit_digit(item.code, 3) %> <%= item.name %></span> <%# 選択リストに表示する項目 %> <span class="informal" style="margin:2.3em"><%= highlight(item.kana, @phrase) %><br /></span> <span class="informal"><%= fit_digit(item.code, 3) %> <%= highlight(item.name, @phrase) %></span> </li> <% end %> <% if params[:payee_account][:bank_id].blank? %> <li> <span connect="payee_account_branch_id"></span> <span connect="branch_kana"></span> <span class="informal">銀行を先に入力してください。</span> </li> <% elsif @items.blank? %> <li> <span connect="payee_account_branch_id"></span> <span connect="branch_kana"></span> <span class="informal">支店が見つかりません。</span> </li> <% end %> </ul>