郵便番号から住所をセット

郵便番号を入力して『住所検索』ボタンを押したら Ajaxでサーバに問合せにいって、コントローラで郵便番号辞書から住所を引っ張って返すというのを作ろうと思って、「待てよ、そういうのって巷に溢れてるんじゃないか?」と思ってググったら、すごくいい JavaScriptのライブラリが見つかったので、これを使わせていただくことにしました。

AjaxZip2のインストール

こちら(→ AjaxZip 2.0 - Ajax郵便番号→住所自動入力フォーム(CGI不要版) )がそのライブラリです。onKeyUpイベントに仕込むようになっているので、『住所検索』ボタンみたいなものは必要ありません。
インストールといっても特別難しいことはなにもなく、一括アーカイブファイルをダウンロードして、適当に展開するだけですが、一応、Railsに組み込む場合の構成を書いておきます。(この通りにすべきというわけではありません)

RAILS_ROOT
  public
    javascripts
      ajaxzip2.js       ← AjaxZip2本体
    ajaxzip2
      data
        zip-001.json    ← 郵便番号データ
        zip-002.json
             :
             :
        zip-999.json

AjaxZip2の組込み

ヘッダに ajaxzip2.jsを入れておきます。

<%= javascript_include_tag 'ajaxzip2', :charset => 'UTF-8' %>
<script>AjaxZip2.JSONDATA = '/ajaxzip2/data';</script>
application.html.erb

charsetを付けるようにとのことですから 'UTF-8'を付けています。AjaxZip2.JSONDATAはディレクトリ指定で、Railsの場合、'/'から始まるのは 'RAILS_ROOT/pubulic/'ということです。データを別の場所に置く場合はここを変えてください。

AjaxZip2の使い方

<%= label_field  f, :zip,      '郵便番号',  6, 8, nil, 
   {:onKeyUp => "AjaxZip2.zip2addr(this, 'user[province]', 'user[address]', null, 'user[address]');"} %><br>
<%= label_select f, :province, '都道府県',  7, select_province %><br>
<%= label_field  f, :address,  '住所',      8, 50 %><br><br>

label_field、label_selectは labelとtext、selectの一緒になったヘルパです。これが展開されるとこう(↓)なります。

<label for="user_zip">郵便番号</label>
<input id="user_zip" name="user[zip]" onKeyUp="AjaxZip2.zip2addr(this, 'user[province]', 'user[address]', null, 'user[address]');" onfocus="this.style.background='#ffc';" size="8" tabindex="6" type="text" />
<br>
<label for="user_province">都道府県</label>
<select id="user_province" name="user[province]" onfocus="this.style.background='#ffc';" tabindex="7">
<option value="" selected="selected">   </option>
<option value="1">北海道</option>
<option value="2">青森県</option>
          :
          :
<option value="47">沖縄県</option></select><br>
<label for="user_address">住所</label>
<input id="user_address" name="user[address]" onfocus="this.style.background='#ffc';" size="50" tabindex="8" type="text" /><br><br>

この『onKeyUp』のところがキモですね。
『AjaxZip2.zip2addr(this, 'user[province]', 'user[address]', null, 'user[address]');』は
『AjaxZip2.zip2addr( '〒上3桁', '都道府県', '市区町村', '〒下4桁', '町域大字', '丁目番地' );』ということだそうです。(互換性を保つというのも大変ですね。引数順序に苦労がしのばれます)

注意点というわけでもないけれど

  • 郵便番号は'-'が入っていてもいなくてもちゃんと動きます。
  • 郵便番号を引っ張ってきたあとのフォーカスもちゃんと住所のところへ来ます。
  • '町域大字'や'丁目番地'に'市区町村'と同じ nameを指定するとちゃんと連結してくれます。(たぶん)

少しはまったところ。
nameを指定すべきなのに idを指定してました。つまり最初、'user[address]'ではなく 'user_address'を指定してました。ところが、IE(8)はこれでなんの問題もなく動くのです。Firefoxでは動かない(そういう :nameがないのでセットしようがない)ので、Firefox固有の問題だと思って、Firebugを使って延々明後日の方向を調べてました。
また、これとはまったく関係がなかったのですが、FirefoxAjax呼び出しのときにエラーが出ることがありました。
JSUnit を Firefox 3 で動作させるメモに書いてある件と同じ『読み込んだファイルと同じディレクトリかそのサブディレクトリしかアクセスできない』という制限に引っかかったと思われます。