概要
住所を入力するフォームでよくある、郵便番号を入力して検索ボタンを押したら、住所が自動入力される機能の作り方のサンプルです。
郵便番号から住所情報をフォームに自動入力をするサンプルは以下になります。
See the Pen 住所自動入力 by take it easy (@take-it-easy) on CodePen.
使用する郵便番号検索API
郵便番号検索APIとは、郵便番号から住所を取得することができるAPIで、今回は、郵便番号データ配信サービス「zipcloud」を使用します。
インターフェース仕様は「zipcloud」に記載があるのでそちらでご確認をしてください。
サンプルコード
HTML
<div class="address-wrapper">
<div class="zip-area" id="zip-area">
<label>郵便番号</label>
<input type="text" name="zip" id="zip" pattern="\d{7}" size="7" required>
<button id="zip-btn" onclick="getZip();">検索</button>
</div>
<div class="address-area">
<label>都道府県</label>
<input type="text" name="address1" id="address1" size=10>
</div>
<div class="address-area">
<label>住所</label>
<input type="text" name="address2" id="address2" size=30>
</div>
</div>
<div class="zip-overlay" id="zip-overlay">
<div id="popup-window">
</div>
</div>
郵便番号、都道府県、住所の入力フォームと、検索ボタンを作成します。
16行目は、郵便番号検索APIより複数の住所が返却された場合(1つの郵便番号に対して住所が重複している場合)にポップアップで住所を選択するためのポップアップを表示するためのエリア用になります。
Javascript
/* ページが開いた時 */
window.onload = function () {
// ポップアップを表示しない
popup_close();
};
/* ポップアップを開く */
function popup_open() {
// ポップアップを表示する
var popup = document.getElementById("zip-overlay");
popup.style.display = "block";
}
/* ポップアップを閉じる */
function popup_close() {
// ポップアップを表示しない
var popup = document.getElementById("zip-overlay");
popup.style.display = "none";
}
/**
* 郵便番号より住所を検索して都道府県・住所に自動入力する。
*/
async function getZip() {
// ダブルクリック防止用
document.getElementById("zip-btn").disabled = true;
// エラーメッセージの有無のチェック
delete_zip_error_msg();
// 都道府県の値を削除
document.getElementById("address1").value = "";
// 住所の値を削除
document.getElementById("address2").value = "";
// 郵便番号の取得
var zip = document.getElementById("zip").value;
// 郵便番号のパターンチェック
var zip_regex = new RegExp(/^\d{7}/);
if (!zip_regex.test(zip)) {
// エラーメッセージの表示
var zip_area = document.getElementById("zip-area");
var zip_err = create_zip_error_msg();
zip_area.appendChild(zip_err);
}
// パターンチェックOKの場合
else {
// 郵便番号検索APIのURL
var url = "https://zipcloud.ibsnet.co.jp/api/search?zipcode=" + zip;
// API呼び出し用のパラメーター
const parameter = {
method: "GET"
};
// API呼び出し
var result = await fetch(url, parameter)
.then((response) => response.json())
.then((data) => {
return data;
});
// statusに200が返却された場合
if (result.status == "200") {
// 住所がない場合
if (result.results == null) {
// エラーメッセージの表示
var zip_area = document.getElementById("zip-area");
var zip_err = create_zip_error_msg();
zip_area.appendChild(zip_err);
}
// 住所がある場合
else {
// 住所が1件の場合
if (result.results.length == 1) {
document.getElementById("address1").value =
result.results[0].address1;
document.getElementById("address2").value =
result.results[0].address2 + result.results[0].address3;
}
// 住所が複数ある場合
else {
// ポップアップウィンドウ
var popup_window = document.getElementById("popup-window");
// ポップアップボディ
var popup_body = create_popup_body();
// 住所の件数分繰り返し
for (i = 0; i < result.results.length; i++) {
var addr1 = result.results[i].address1;
var addr2 = result.results[i].address2;
var addr3 = result.results[i].address3;
// ラジオボタンの作成
var address_radio = create_address_radio(addr1, addr2, addr3);
// 最初のラジオボタンにはチェックをつける
if (i == 0) address_radio.checked = true;
// ラベルの作成
var address_label = document.createElement("label");
address_label.setAttribute("for", "address_radio_" + i);
var address_label_value = document.createTextNode(
addr1 + addr2 + addr3
);
address_label.appendChild(address_label_value);
// ポップアップボディにラジオボタンを追加
popup_body.appendChild(address_radio);
// ポップアップボディにラベルを追加
popup_body.appendChild(address_label);
// ポップアップボディに改行を追加
var br = document.createElement("br");
popup_body.appendChild(br);
}
// 選択ボタンをポップアップボディに追加
var btn = create_select_address_button();
popup_body.appendChild(btn);
// ポップアップウィンドウにポップアップボディを追加
popup_window.appendChild(popup_body);
// ポップアップを表示
popup_open();
}
}
}
// statusに200以外が返却された場合
else {
// エラーメッセージの表示
var zip_area = document.getElementById("zip-area");
var zip_err = create_zip_error_msg();
zip_area.appendChild(zip_err);
}
}
// ボタンを押せるようにする。
document.getElementById("zip-btn").disabled = false;
}
/**
* エラーメッセージがある場合は削除する。
*/
function delete_zip_error_msg() {
var zip_area = document.getElementById("zip-area");
var zip_err = zip_area.getElementsByClassName("err_msg");
if (zip_err.length != 0) {
zip_err[0].remove();
}
}
/**
* エラーメッセージを作成
*/
function create_zip_error_msg() {
var zip_err = document.createElement("p");
var zip_err_msg = document.createTextNode(
"郵便番号を正しく入力してください。"
);
zip_err.appendChild(zip_err_msg);
zip_err.setAttribute("class", "err_msg");
return zip_err;
}
/**
* ポップアップボディを作成
*/
function create_popup_body() {
var popup_body = document.createElement("div");
popup_body.setAttribute("id", "popup-body");
return popup_body;
}
/**
* 住所のラジオボタンの作成
*/
function create_address_radio(addr1, addr2, addr3) {
var address_radio = document.createElement("input");
address_radio.setAttribute("type", "radio");
address_radio.setAttribute("name", "address_radio");
address_radio.setAttribute("id", "address_radio_" + i);
// カンマ区切りで都道府県と住所に分けられるようにする
address_radio.value = addr1 + "," + addr2 + addr3;
return address_radio;
}
/**
* 住所のラジオボタンのラベルの作成
*/
function create_address_label(addr1, addr2, addr3) {
// ラベル
var address_label = document.createElement("label");
address_label.setAttribute("for", "address_radio_" + i);
// 表示する住所
var address_label_value = document.createTextNode(addr1 + addr2 + addr3);
address_label.appendChild(address_label_value);
return address_label;
}
/**
* 選択ボタンを作成
*/
function create_select_address_button() {
var btn = document.createElement("button");
var btn_txt = document.createTextNode("選択");
btn.appendChild(btn_txt);
btn.setAttribute("type", "button");
btn.setAttribute("onclick", "select_address();");
return btn;
}
/**
* 選択ボタンが押された場合
*/
function select_address() {
// ポップアップを閉じる
popup_close();
// ラジオボタンをの値を取得
var radio = document.getElementsByName("address_radio");
var value = "";
for (i = 0; i < radio.length; i++) {
if (radio.item(i).checked) {
value = radio.item(i).value;
}
}
// カンマ区切りで都道府県と住所に分ける
var address = value.split(",");
// 都道府県
document.getElementById("address1").value = address[0];
// 住所
document.getElementById("address2").value = address[1];
// ポップアップボディを削除
document.getElementById("popup-body").remove();
}
/**
* 郵便番号
*/
var zip = document.getElementById("zip");
/**
* 郵便番号にフォーカスが当たった場合のイベント
*/
zip.addEventListener("focus", function () {
// エラーメッセージの削除
delete_zip_error_msg();
});
/**
* 郵便番号に入力があった場合のイベント
*/
zip.addEventListener("input", function () {
// 都道府県の値を削除
document.getElementById("address1").value = "";
// 住所の値を削除
document.getElementById("address2").value = "";
});
59行目で、郵便番号検索APIの呼び出しを行います。
68行目〜73行目は、郵便番号検索APIより住所が返却されなかった場合(0件で住所がない場合)の処理です。
76行目〜81行目は、郵便番号検索APIより1件住所が返却された場合の処理です。
85行目〜129行目は、郵便番号検索APIより複数住所が返却された場合の処理です。
返却された住所情報をポップアップで選択できるようにポップアップを構築しています。
CSS
.address-wrapper {
width: 300px;
margin: 0 auto;
}
.zip-area,
.address-area {
padding-top: 4px;
padding-bottom: 4px;
padding-left: 10px;
}
.zip-area label,
.address-area label {
display: block;
font-size: 13px;
}
/* エラーメッセージ */
.err_msg {
margin: 0;
padding: 0;
color: #f00;
}
/* ポップアップが開いた時のオーバレイ */
.zip-overlay {
display: block;
position: fixed;
top: 0;
left: 0;
height: 100vh;
width: 100%;
background-color: rgba(0, 0, 0, 0.3);
}
/* ポップアップ */
#popup-window {
width: 500px;
height: auto;
background-color: #fff;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 10px;
}
/* ポップアップの内容 */
#popup-body {
padding: 20px 10px;
}
今回はデザインはあまり考慮していません。
エラーメッセージ、ポップアップについては多少デザインが必要だったのでそちらは参考にしてみてください。