検索可能なプルダウンリストで3箇所以上のフォームを更新する。

前々回のid属性に欲しい値を設定する方法では、選択リストをクリックした時に更新するフォームが3箇所以上になってしまうと、やってやれないことはないが、設定するのが面倒な状況になる。実際にやってみる。以下のようなコードにしてみた。

  • 空のspanタグのid属性を、selectedItem.firstChild.id、selectedItem.firstChild.nextSibling.id、...と順に取得して行くことにした。
<%# ビュー %>
<%= text_field_with_auto_complete :bank, :kana, 
      {}, :after_update_element=>"function(element, selectedItem){$('payee_account_bank_id').value = selectedItem.id;
                                                                  $('bank_id').value = selectedItem.firstChild.id;
                                                                  $('bank_name').value = selectedItem.firstChild.nextSibling.id;}" %>
<%= hidden_field :payee_account, :bank_id %>
<%= text_field :bank, :id %>
<%= text_field :bank, :name %>
  • 空のspanタグのid属性に欲しい値を設定した。
<%# ビュー_auto_complete_for_bank_kana.rhtml %>
<%# 字下げと改行を入れると余分なスペースが入ってしまうが、ここでは見易くするために整形した。 %>
<ul>
  <% @items.each do |item| %>
    <li id=<%= item.id %>>
      <span id=<%= item.id %>></span>
      <span id=<%= item.name %>></span>
      <%= item.kana %>
    </li>
  <% end %>
</ul>
  • これで、更新箇所がいくつ増えても対応はできるようになったが、シンプルじゃない...。
  • selectedItem.firstChild.nextSibling.idじゃ、何を指定しているんだか分かり難い...。

これじゃ、やっつけ仕事だなーと悲観していると、舞波さんのところで、素晴らしい方法が提示されていました!(感謝です)

multicontrols.jsで拡張する

  • ソースはtagged with "autocomplete" on Developer's Blog表示されているので、コピーして、public/javascripts/multicontrols.jsとして保存する。(このソースはafterUpdateElementの不具合は修正済のようだ。)
  • <%= javascript_include_tag 'multicontrols' %>を忘れずに。
やっつけ仕事と同じことをmulticontrols.jsを利用してやってみる
  • :after_update_elementは不要になってしまった。シンプル!
<%# ビュー %>
<%= text_field_with_auto_complete :bank, :kana %>
<%= hidden_field :payee_account, :bank_id %>
<%= text_field :bank, :id %>
<%= text_field :bank, :name %>
  • 空のspanタグのconnect属性に、設定したいフォームのid属性を指定すると、そのフォームに値が設定される。
  • connect属性が指定されていない部分は、値が設定されない。(bank_kanaであっても必ずconnect属性を指定する必要あり。)
  • 字下げによる不要なスペース問題も、spanタグの中で余分なスペースがなければ良い。見やすくなった!
<%# ビュー_auto_complete_for_bank_kana.rhtml %>
<ul>
  <% @items.each do |item| %>
    <li>
      <span connect="payee_account_bank_id"><%= item.id %></span>
      <span connect="bank_id"><%= item.id %></span>
      <span connect="bank_name"><%= item.name %></span>
      <span connect="bank_kana"><%= item.kana %></span>
    </li>
  <% end %>
</ul>

これなら、更新箇所がいくつに増えても、手軽に追記できる。multicontrols.js、素晴らしいです!

      • connect属性を作り出す発想が、自分にも欲しい...。