add to hatena hatena.comment (0) add to del.icio.us (0) add to livedoor.clip (0) add to Yahoo!Bookmark (0) Total: 0

Webサービスを利用したAJAX郵便番号検索

郵便番号から住所を検索したり、住所から郵便番号を検索するTipsは様々なサイトで公開されています。
大体の場合は、郵便事業株式会社様(旧日本郵政公社)が提供しているCSVデータをDBに保持して・・という形式が多いようです。
確かに自前でDBを用意して検索アプリを作成し、郵便番号情報を常に最新にメンテナンスできる環境があれば、最善の方法です。
ただ、「そこまでは必要ないけども、もっと簡単に実装したい」という場合を想定して、WEBサービスを利用し簡単に実装するサンプルを作成しました。

今回のサンプルはこちらで確認できます。

よくある住所欄の入力フォームで
・郵便番号を入力するとオートコンプリート形式で該当住所を表示
・住所をクリックすると入力フォーム内の住所欄に値を代入する
というものです。

WEBサービスについて

郵便番号検索のWEBサービスはいくつか公開されていたのですが、グルーブテクノロジー株式会社様の仕様がわかり易く、複数の形式にも対応していますので、今回はこちらのサービスを利用させて頂きました。

仕組みの概要

リクエストの流れは以下のようになります。
クライアントjs → サーバー側PHP → WEBサービス → サーバー側PHP → クライアントjs

1.javascriptで郵便番号フィールドを定期的に監視
2.値に変化があれば、値をパラメータとしてサーバー側のPHPを経由してWEBサービスにリクエストを送信(REST)
3.WEBサービスからの結果をPHPで加工し、クライアント側へ送信
4.結果データのクリックイベントに値をフィールドに反映させる処理を追加

※WEBサービスはJSONPを使えばサーバーPHPを介さずに直接データを取得することも可能です

実装方法

HTML内でprototype.jsと今回作成したctl_auto_zip.jsを読み込み、scriptタグでajax部分の初期化を行います。
CtlAutoZipクラスの各引数は、郵便番号、都道府県、市区郡、それ以下の住所 を格納する各フィールドのエレメントIDを指定します。

HTML:
  1. <script type="text/javascript" src="/sample/zip_code/prototype.js"></script>
  2. <script type="text/javascript" src="/sample/zip_code/ctl_auto_zip.js"></script>
  3.     new CtlAutoZip('zip', 'pref', 'addr1', 'addr2');
  4. </script>
  5. 中略
  6.     <td valign="top">郵便番号</td>
  7.     <td>
  8.         <input type="text" name="zip" id="zip" value="" style="width:60px" />
  9.     </td>
  10. </tr>
  11.     <td>都道府県</td>
  12.     <td>
  13.         <input type="text" name="pref" id="pref" value="" style="width:100px" />
  14.     </td>
  15. </tr>
  16.     <td>住所1</td>
  17.     <td>
  18.         <input type="text" name="addr1" id="addr1" value="" style="width:300px" />
  19.     </td>
  20. </tr>
  21.     <td>住所2</td>
  22.     <td>
  23.         <input type="text" name="addr2" id="addr2" value="" style="width:300px" />
  24.     </td>
  25. </tr>

ソースコード

ctl_auto_zip.js
※スクリプト内のthis.server_urlの設定は次のPHPファイルのパスに変更する必要があります。

JAVASCRIPT:
  1. /***
  2. * AutoZip Control
  3. */
  4. var CtlAutoZip = Class.create({
  5.     initialize: function(zip_id, pref_id, city_id, town_id){
  6.         this.zip_id  = zip_id;
  7.         this.pref_id = pref_id;
  8.         this.city_id = city_id;
  9.         this.town_id = town_id;
  10.        
  11.         this.server_url  = '/sample/zip_code/ajax_zip_code.php';
  12.         this.zip_list_id = 'auto_zip_list';
  13.         this.zip_value   = '';
  14.        
  15.         this.load();
  16.     },
  17.    
  18.     load: function(){
  19.         document.observe('dom:loaded', function() {
  20.             // 郵便番号の初期値
  21.             this.zip_value = $F(this.zip_id);
  22.            
  23.             // Ajaxの監視イベント設定
  24.             new PeriodicalExecuter(this.ajax_zip.bind(this), 0.5);
  25.            
  26.             // 候補リストを閉じる
  27.             $(this.pref_id).observe('focus', function(event){
  28.                 $(this.zip_list_id).hide();
  29.             }.bind(this));
  30.            
  31.             $(this.city_id).observe('focus', function(event){
  32.                 $(this.zip_list_id).hide();
  33.             }.bind(this));
  34.            
  35.             $(this.town_id).observe('focus', function(event){
  36.                 $(this.zip_list_id).hide();
  37.             }.bind(this));
  38.            
  39.             // 候補リストのエレメントを作成
  40.             $(this.zip_id).insert({
  41.                 after: '<div id="' +this.zip_list_id+ '" style="display:none;position:absolute;z-index:999;background-color:lightyellow;border:solid 1px silver;padding:2px"></div>'
  42.             });
  43.         }.bind(this));
  44.     },
  45.    
  46.     ajax_zip: function(){
  47.         if(this.zip_value == $F(this.zip_id)) return;
  48.         this.zip_value = $F(this.zip_id);
  49.        
  50.         new Ajax.Updater(
  51.             this.zip_list_id,
  52.             this.server_url,
  53.             {
  54.                 "method": "get",
  55.                 "parameters": "zip=" + this.zip_value,
  56.                
  57.                 onSuccess: function(request) {
  58.                     if(request.responseText == ''){
  59.                         $(this.zip_list_id).hide();
  60.                     }else{
  61.                         $(this.zip_list_id).show();
  62.                     }
  63.                 }.bind(this),
  64.                
  65.                 onComplete: function(request) {
  66.                     // コンテナ内のリンク処理
  67.                     $$('#' + this.zip_list_id + ' a').each(function(anchor){
  68.                         if(anchor.identify() == 'auto_zip_credit'){
  69.                             return;
  70.                         }
  71.                         anchor.observe('click', function(){
  72.                             var text = anchor.innerHTML;
  73.                             var a = text.split(' ');
  74.                             if(a[0]) this.zip_value = a[0];
  75.                             if(a[0]) $(this.zip_id).setValue(a[0]);
  76.                             if(a[1]) $(this.pref_id).setValue(a[1]);
  77.                             if(a[2]) $(this.city_id).setValue(a[2]);
  78.                             if(a[3]) $(this.town_id).setValue(a[3]);
  79.                             $(this.zip_list_id).hide();
  80.                         }.bind(this));
  81.                     }.bind(this));
  82.                 }.bind(this),
  83.                
  84.                 onFailure: function(request) {
  85.                     $(this.zip_list_id).hide();
  86.                 }.bind(this),
  87.                
  88.                 onException: function (request) {
  89.                     $(this.zip_list_id).hide();
  90.                 }.bind(this)
  91.             }
  92.         );
  93.     }
  94. });

サーバー側PHPスクリプト
ajax_zip_code.php (PHP5専用)

PHP:
  1. <?php
  2.     header('Content-Type: text/html; charset=UTF-8');
  3.     $base_url = 'http://groovetechnology.co.jp/ZipSearchService/v1/zipsearch?';
  4.    
  5.     if(!isset($_GET['zip'])) exit();
  6.     $zip = $_GET['zip'];
  7.     $zip = mb_convert_kana($zip, 'n');
  8.     $zip = str_replace('-', '', $zip);
  9.    
  10.     // 2バイト以下のパラメータでは実行しない
  11.     if(strlen($zip) <= 2) exit();
  12.    
  13.     if(ereg("^[0-9]+$", $zip)){
  14.         // 郵便番号検索
  15.         $zip = ereg_replace("[^0-9]", "", $zip);
  16.         $zip = substr($zip, 0, 7);
  17.         $param = 'zipcode=' .$zip;
  18.     }else{
  19.         // 住所検索
  20.         $param = 'word=' .$zip;
  21.     }
  22.    
  23.     $xmlstr = @file_get_contents($base_url. $param. '&format=xml');
  24.     if($xmlstr == '') exit();
  25.    
  26.     $xml = @simplexml_load_string($xmlstr);
  27.    
  28.     if(!$xml->address) exit();
  29.     if(count($xml->address)> 100) {
  30.         echo '対象が100件以上存在しています';
  31.         exit();
  32.     }
  33.     foreach($xml->address as $row){
  34.         echo_html(
  35.             $row->zipcode,
  36.             $row->prefecture,
  37.             $row->city,
  38.             $row->town
  39.         );
  40.     }
  41.     echo_credit();
  42.     exit();
  43.    
  44.     function echo_html($zip, $pref, $city, $town){
  45.         // 文字整形
  46.         $delete = array(
  47.             '(次のビルを除く)',
  48.             '以下に掲載がない場合',
  49.         );
  50.         $town = str_replace($delete, '', $town);
  51.         echo sprintf(
  52.             '<div><a href="javascript:void(0)">%s %s %s %s</a></div>',
  53.             $zip, $pref, $city, $town
  54.         );
  55.     }
  56.    
  57.     function echo_credit(){
  58.         echo '<div style="margin-top:2px;text-align:right"><a id="auto_zip_credit" href="http://groovetechnology.co.jp/webservice/" target="_blank" style="font-size:11px;color:blue;border:0">グルーブテクノロジー Web サービス</a></div>';
  59.     }
  60. ?>

ダウンロード

今回のサンプルソースは下記からダウンロードできます。
ajax_zip_code.zip

関連するその他の記事

  • No Related Post

Comments

Leave a Reply