Sử dụng Google Geocoding API để tạo Form điền địa chỉ từ số bưu điện (郵便番号)

Chào các bạn Nếu như các bạn hay phát triển sản phẩm cho khách hàng Nhật thì hẳn các bạn sẽ biết đến một tính năng rất hay được sử dụng trong các service Web hay App của Nhật đó chính là nhập số bưu điện 郵便番号 để từ đó search ra địa chỉ và auto điền vào các trường Hiện tại cho đến bây giờ mình thường làm theo cách cổ điển đó là lên trang web Bưu điện chính thức của Nhật để Download file Data về dữ liệu số bưu điện- địa chỉ và import vào hệ thống sử dụng local. Tuy nhiên có một điều hơi phiền phức đó là không biết rằng khoảng bao lâu thì dữ liệu này được update, và mình cần phải import lại để update khá là bị động. Chính vì vậy mà ở bài viết này mình xin giới thiệu đến các bạn một cách tiện lợi hơn đó là việc sử dụng Google Maps Geocoding API để get dữ liệu địa chỉ về rất đơn giản 😄 :crazy_face: Kết quả cuối cùng của Page nó sẽ như sau :

Lấy thông tin địa chỉ từ JSON

Khi sử dụng Ajax để request lên Google Maps Geocoding API chúng ta sẽ nhận được response dạng Json, Nội dung Response có dạng như sau

Request: https://maps.googleapis.com/maps/api/geocode/json?address=160-0002&language=ja&sensor=false Dù có dấu gạch ngang hay không ở phần số bưu điện thì vẫn được tính là hợp lệ và chạy ngon nhé :kiss_ww:

{
   "results" : [
      {
         "address_components" : [
            {
               "long_name" : "160-0002",
               "short_name" : "160-0002",
               "types" : [ "postal_code" ]
            },
            {
               "long_name" : "坂町",
               "short_name" : "坂町",
               "types" : [ "sublocality_level_1", "sublocality", "political" ]
            },
            {
               "long_name" : "新宿区",
               "short_name" : "新宿区",
               "types" : [ "locality", "political" ]
            },
            {
               "long_name" : "東京都",
               "short_name" : "東京都",
               "types" : [ "administrative_area_level_1", "political" ]
            },
            {
               "long_name" : "日本",
               "short_name" : "JP",
               "types" : [ "country", "political" ]
            }
         ],
         "formatted_address" : "〒160-0002, 日本",
         "geometry" : {
            "bounds" : {
               "northeast" : {
                  "lat" : 35.692041,
                  "lng" : 139.7292123
               },
               "southwest" : {
                  "lat" : 35.688532,
                  "lng" : 139.7246218
               }
            },
            "location" : {
               "lat" : 35.6907555,
               "lng" : 139.7272033
            },
            "location_type" : "APPROXIMATE",
            "viewport" : {
               "northeast" : {
                  "lat" : 35.692041,
                  "lng" : 139.7292123
               },
               "southwest" : {
                  "lat" : 35.688532,
                  "lng" : 139.7246218
               }
            }
         },
         "place_id" : "ChIJoebNl_SMGGAR4LtICJbkh5I",
         "types" : [ "postal_code" ]
      }
   ],
   "status" : "OK"
}

Hoá ra là như vậy, ở trong mảng address_components chúng ta có các phần tử thông tin lần lượt của quốc gia, tỉnh, phủ (thị trấn), địa chỉ khu dân cư phải không? Rất là dễ dùng. Chúng ta cũng có thể sử dụng được cả thông tin Code của quốc gia, và các thông tin kinh độ vĩ độ nữa ^^. Tuy ở bài toán này thì chưa cần thiết 😄

Sample Source Code

Sau khi sử dụng API để gọi Ajax như bên trên, từ giá trị trả về chúng ta tiến hành import vào các trường trong form. Nội dung chi tiết các bạn tham khảo ở Source code dạng CSS sau nhé. (Sử dụng JQuery)

  • sample.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="css/zip.css">
</head>
<body>
  <div class="wrapper">
    <div class="content">
      <label>郵便番号</label>
      <span class="content_form">
        <input id="zip" name="zip" type="text" placeholder="1600002"/>
      </span>
      <span class="content_form">
        <input class="studentEnrollment_button" type="button" value="住所を自動で入力する" onClick="setState()" />
      </span>
    </div>
    <div class="content">
      <label>都道府県</label>
      <span class="content_form">
        <input id="state" name="state" type="text" placeholder="東京都" />
      </span>
    </div>
    <div class="content">
      <label>市区町村</label>
      <span class="content_form">
        <input id="city" name="city" type="text" placeholder="新宿区" />
      </span>
    </div>
    <div class="content">
      <label>番地</label>
      <span class="content_form">
        <input id="address1" name="address1" type="text" placeholder="西新宿666" />
      </span>
    </div>
    <div class="content">
      <label>建物名・階・部屋番号</label>
      <span class="content_form">
        <input id="address2" name="address2" type="text" placeholder="ビルヂング666" />
      </span>
    </div>
  </div>
</body>
<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script>
  // 郵便番号から住所を取得
  function setState() {
    var zip = $('#zip').val();

    // ここでzipのバリデーションを行ってください

    $.ajax({
      type : 'get',
      url : 'https://maps.googleapis.com/maps/api/geocode/json',
      crossDomain : true,
      dataType : 'json',
      data : {
        address : zip,
        language : 'ja',
        sensor : false
      },
      success : function(resp){
        if(resp.status == "OK"){
          // APIのレスポンスから住所情報を取得
          var obj = resp.results[0].address_components;
          if (obj.length < 5) {
            alert('正しい郵便番号を入力してください');
            return false;
          }
          //$('#country').val(obj[4]['long_name']); // 国
          $('#state').val(obj[3]['long_name']); // 都道府県
          $('#city').val(obj[2]['long_name']);  // 市区町村
          $('#address1').val(obj[1]['long_name']); // 番地
        }else{
          alert('住所情報が取得できませんでした');
          return false;
        }
      }
    });
  }
</script>
</html>
  • zip.css
body{
  font-family: Helvetica ,"游ゴシック" ,"Yu Gothic" ,sans-serif;
}
.wrapper {
  margin: 0 auto;
  width: 600px;
}
.content {
  display: table;
  width: 100%;
  border-top: 1px solid #DB7093;
  border-left: 1px solid #DB7093;
  border-right: 1px solid #DB7093;
}
.content:last-child {
  border-bottom: 1px solid #DB7093;
}
.content label{
  display: table-cell;
  width: 200px;
  background-color: #DB7093;
  color: white;
  font-size: 16px;
  vertical-align: middle;
  text-indent: 1em;
}
.content .content_form {
  display: table-cell;
  padding: 10px
}
input[type="text"] {
  width: 100%;
  height: 35px;
  font-size: 18px;
  vertical-align: top;
  padding-left: 5px;
}
input[type="button"] {
  width: 100%;
  height: 40px;
  font-size: 16px;
  cursor: pointer;
  border: 1px solid gray;
  vertical-align: top;
  background-color: lightgray;
}

Kết quả

Sau khi chạy code chúng ta có kết quả như bên trên!!!

Lưu ý

Nếu các bạn dùng free thì chúng ta cần lưu ý đó là ở mode free sẽ bị hạn định số lần request trên một ngày (2500 per day, 50 per second), chi tiết hãy tham khảo ở đây nhé https://developers.google.com/maps/documentation/geocoding/usage-limits#header_3

Tham khảo : Qiita