prototype.jsを使ってみる
Web2.0と言われて久しい中、あんまり真面目に取り組んでいないのでここでちょこっと練習を兼ねてテストを載せてみます。以前にもやってはいるのですがちゃんと書き留めていないのでここで紹介しておきます。今回のケーススタディは、住所登録フォームのアシスト(郵便番号検索)です。
基本的にAjaxが呼び出すCGIは機能だけを説明するのでPerlなりPHPなりで同様のものを用意して下さい。ここで使用するのは3つのCGI(pref.cgi, city.cgi, zip.cgi)です。そしてデータベースには3つのテーブル(pref_table, city_table, zip_table)があると想定して下さい。
pref_table(都道府県名を管理)
- pref_id int(2) unsigned NOT NULL auto_increment #都道府県ID
- name text NOT NULL #都道府県名
city_table(市町村名を管理)
- city_id int(5) unsigned NOT NULL auto_increment #市町村ID
- pref_id int(2) unsigned NOT NULL #都道府県ID
- name text NOT NULL #市町村名
zip_table(郵便番号と地先名を管理)
- zip_id int(11) unsigned NOT NULL auto_increment #郵便番号ID
- zip_code int(7) unsigned NOT NULL #郵便番号
- pref_id int(2) unsigned NOT NULL #都道府県ID
- city_id int(5) unsigned NOT NULL #市町村ID
- name text NOT NULL #地先名
pref.cgi(都道府県の選択肢を戻す)
<option>都道府県を選択</option> <option value="1">北海道</option> <option value="2">青森県</option> ... <option value="47">沖縄県</option>
city.cgi(都道府県IDを渡すと市町村の選択肢を戻す、ex:pref=1)
<option value="1001">札幌市中央区</option> <option value="1002">札幌市北区</option> ... <option value="1189">目梨郡羅臼町</option>
zip.cgi(郵便番号を渡すと都道府県ID、市町村ID、地先名の選択肢を戻す、ex:zip=0820074)
<li id="6999">820074<span class="informal">北海道河西郡芽室町栄柏友</span><input id="data6999" value="1:1167:栄柏友" type="hidden" /></li> <li id="7000>820074<span class="informal">北海道河西郡芽室町栄光栄</span><input id="data7000" value="1:1167:栄光栄" type="hidden" /></li> ... <li id="7003>820074<span class="informal">北海道河西郡芽室町栄丸山</span><input id="data7003" value="1:1167:栄丸山" type="hidden" /></li>
以上が下準備です。ここまで準備すれば後はHTML側での作業だけです。
ではまずフォームの部分はこうです。
<form> <label for="title">郵便番号:</label> <input autocomplete="off" name="zip" id="zip" value="" type="text" /> <div class="auto_complete" id="zip_auto_complete"></div> <label for="title">住所:</label> <select name="pref" id="pref" onChange="chPref();"></select> <select name="city" id="city" onChange="document.getElementById('address').value='';"> <option>市町村を選択</option> </select> <input name="address" id="address" value="" type="text" /> </form>
次にjavascriptの部分です。まずはロード時に都道府県の選択肢を読み込む部分。
new Ajax.Updater( 'pref','pref.cgi', {onComplete: iePatch1} );
これだけです。簡単ですよね。pref.cgiを呼び出してid'pref'の内容をアップデートせよというコマンド。次に都道府県を選択した時に市町村の選択肢を読み込む部分。
function chPref() { new Ajax.Updater( 'city','city.cgi', { parameters: 'pref='+document.getElementById('pref').value, onComplete: iePatch2, asynchronous: 1 } ); }
これだけです。これも簡単ですよね。これはid'pref'のvalueをcity.cgiに送って戻してきた内容でid'city'をアップデートせよというコマンド。本当は郵便番号から検索できれば良いので上の2つはなくても良いのですが一応、都道府県を選択して市町村を選択する人のための機能です。そしてコレが本命の郵便番号を入力すると該当地先名を戻す部分。
new Ajax.Autocompleter( 'zip', 'zip_auto_complete', 'zip.cgi', {minChars: 7,afterUpdateElement : getSelectionId} );
これはid'zip'のvalueが7字になったらzip.cgiにその内容を送って戻してきた内容でid'zip_auto_complete'をアップデートせよと言うコマンド。戻してきたリストから地先名を選んだ後にgetSelectionIdを実行する様にしてあるので、最後に選んだ地先名で必要項目を入れる部分
function getSelectionId(text, li) { var itemName = 'data' + li.id; var dataArray = document.getElementById(itemName).value.split(":"); document.getElementById('pref').value = dataArray[0]; new Ajax.Updater( 'city','city.cgi', { parameters: 'pref='+dataArray[0],onComplete: iePatch2, onSuccess: function(){ document.getElementById('city').value = dataArray[1];},asynchronous: 1 } ); document.getElementById('address').value = dataArray[2]; }
こんな感じです。説明しますと選んだ項目(li)のidから隠された'data***(id)'のvalueを読み取って、":"で都道府県IDと市町村IDと地先名に分割して、id'pref'の項目を都道府県IDのものを選択、id'city'はcity.cgiに送った都道府県IDで内容を更新してその中の市町村IDのものを選択、最後にid'address'に地先名を入力するというものです。
※IEでは上手く動いていなかったので修正しました。<SELECT>の<OPTION>を外部から読み込むと上手く表示できなかったみたいです。以下が追加ファンクションです。コレに絡んだ部分のスクリプトも書き換えてあります(太字部)。
function iePatch1(req){ document.getElementById('pref').outerHTML = '<select name="pref" id="pref" onChange="chPref();">' + req.responseText + "</select>"; } function iePatch2(req){ document.getElementById('city').outerHTML = '<select name="city" id="city" onChange="document.getElementById(\'address\').value=\'\';">' + req.responseText + "</select>"; }
実際に動かすとこんな感じです。
地先名が戻される<div class="auto_complete" id="zip_auto_complete"></div>はスタイルシートで背景を指定しておかないと、後ろのコンテンツに重なってしまうので注意!後は自分でいじって試してみて下さい。
※これ意外と最初のデータベースのテーブルを作る作業が大変です。郵便番号等のダウンロードはここから行えます。でもこれ自体は地先名→郵便番号って流れで探すように作られているからチョット加工が必要です。頑張ってみて下さい。Google Mapに飛ばすのはおまけです(郵便番号検索の結果を反映するので内容を変えてもダメですよ)。
コメントする