【タブ切り替え】地方-都道府県-市区町村が連動【PHP + jQuery + json】
この記事は、最初の投稿から4年以上が経過しています。
最終更新から1493日が経過しています。
「地方-都道府県-市区町村の3つが連動するタブ切り替えをしたい」
「タブ切り替えの地方区分や対応する都道府県を、自分のサービスにあわせてカスタマイズしたい」
「できるだけコピペをする手間は省きたい」
こんな悩みに応えられるサンプルをつくってみました。
ポイントは…
- デモをコピペすればプログラムの知識は必要ない (カスタマイズは知識が必要)
- 地方、都道府県はjsonファイルを手動で編集する
- 市区町村のjsonファイルはPHPでAPIから取得する
- jQueryはdata属性を使うのでちょっと難しいかも (こだわりがなければ編集する必要はない)
- 都道府県名・市区町村名をHTMLに直書きするのでSEOにも良い効果が期待できる
PHPがわかれば修正などがしやすくできますが、できあがっているデモのHTMLをコピペしてしまえばPHPの知識がなくても動作は実現できます。
私は、2015年からWeb制作の仕事をはじめて、170件ほどのWebサイトを制作してきました。
その間、いろいろな失敗を繰り返し、クライアントからのフィードバックや本などで勉強することにより、多くのノウハウを得ることができました。
記事を読み終えると、地方-都道府県-市区町村が連動するタブ切り替えをつくることができます。
シンプルなタブ切り替えはこちらの記事で解説しています。
CSS、JavaScript、jQueryそれぞれの方法を解説しています。
Webサイトでタブ切り替えする方法 3選【CSS・JavaScript・jQuery】
Webサイトでタブ切り替えする方法を知りたいですか?この記事では、タブ切り替えする方法をCSS、JavaScript、jQueryのそれぞれで紹介しています。ぜひご覧ください。
- 目次
地方-都道府県-市区町村が連動するタブ切り替えをつくる方法
以下のような構成になるようにファイルを配置していきます。
- index.php
- region.json
- pref.json
- city.json
jsonファイルを作成・編集する
地方のjsonを手動で編集する
「region.json」を編集します。
以下のような地方区分であればそのままで編集する必要はありません。
地方区分が少なかったり、違う地方区分が必要であればjsonのルールで編集してください。
「name_en」はWordPressのslugのようなものなので、日本語や記号を避ければ、わかりやすい単語にしてもかまいません。
[
{
"id": "1",
"name": "北海道",
"name_en": "hokkaido"
},
{
"id": "2",
"name": "東北",
"name_en": "tohoku"
},
{
"id": "3",
"name": "関東",
"name_en": "kanto"
},
{
"id": "4",
"name": "中部",
"name_en": "chubu"
},
{
"id": "5",
"name": "近畿",
"name_en": "kinki"
},
{
"id": "6",
"name": "中国",
"name_en": "chugoku"
},
{
"id": "7",
"name": "四国",
"name_en": "shikoku"
},
{
"id": "8",
"name": "九州沖縄",
"name_en": "kyushu-okinawa"
}
]
都道府県のjsonを手動で編集する
「pref.json」を編集します。
以下のような一般的な都道府県すべてで地方区分が同じであればそのままで編集する必要はありません。
「region.json」のidを「pref.json」のregionに書いていきます。
これでどの都道府県がどの地方なのかを決めていきます。
「name_en」はWordPressのslugのようなものなので、日本語や記号を避ければ、わかりやすい単語にしてもかまいません。
※頭文字が大文字になっていますが小文字のほうがいいです。
[
{
"code": "1",
"name": "北海道",
"name_en": "Hokkaido",
"region": "1"
},
{
"code": "2",
"name": "青森県",
"name_en": "Aomori",
"region": "2"
},
{
"code": "3",
"name": "岩手県",
"name_en": "Iwate",
"region": "2"
},
{
"code": "4",
"name": "宮城県",
"name_en": "Miyagi",
"region": "2"
},
{
"code": "5",
"name": "秋田県",
"name_en": "Akita",
"region": "2"
},
同じパターンで繰り返し
{
"code": "46",
"name": "鹿児島県",
"name_en": "Kagoshima",
"region": "8"
},
{
"code": "47",
"name": "沖縄県",
"name_en": "Okinawa",
"region": "8"
}
]
PHPで市区町村を取得しjsonを作成する
「city.json」は47都道府県の市区町村をすべて手動で編集していくのは現実的ではないのでPHPを使って自動で作成します。
国土交通省の都道府県内市区町村一覧取得APIを使って取得します。
例えば東京都の場合は、以下のURLで東京都の市町村をjson形式で取得できます。
アクセスがあるたびに、すべての都道府県APIを取得していると読み込み速度が遅くなったり、スパム扱いされてアクセスが制限される可能性があるので、自分のサーバーに「city.json」をつくり、必要な都道府県を書き込み保存します。
「city.json」がない場合のみ、「city.json」を作成、更新するようにします。
一度、必要なファイルが作成できたら削除、コメントアウトしてかまいません。
注意点としては、「pref.json」をそのまま47都道府県にしている場合は、foreach文で47回ループしてしまいます。
制作時、テスト時には不要なループをしないように数を減らしたほうがいいです。
ここでは市区町村を個別に除外する方法は解説していません。
// jsonファイル取得関数
function get_json( $path ){
$json = file_get_contents( $path );
$json = mb_convert_encoding($json, "UTF8", "ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN");
$json_decode = json_decode($json,true);
return $json_decode;
}
// 市町村 city.json作成
$file_name = "city.json";
if( !file_exists( $file_name ) ){
$api = "https://www.land.mlit.go.jp/webland/api/CitySearch";
$cities = [];
foreach( $pref as $key => $value ){
if( $value["region"] ){
$code = sprintf( "%02d", $value["code"] );
$url = $api . "?area=" . $code;
$city = get_json( $url );
$cities[ $value["code"] ] = $city["data"];
}
}
$json_encode = json_encode( $cities, JSON_UNESCAPED_UNICODE );
//var_dump( $cities );
$json = fopen( $file_name, "w+b");
fwrite( $json, $json_encode );
fclose( $json );
}
jsonファイルからPHPファイルにHTMLを書き出す
地方、都道府県、市区町村のjsonファイルから、PHPファイルにそれぞれHTMLに書き出します。
地方、都道府県はul、liタグで書き出し、市区町村は都道府県ごとに区切ってul、liで書き出します。
地方と都道府県の連動にはdata-region属性、都道府県と市区町村の連動にはdata-pref属性を使います。
このdata属性をjQueryで使ってタブを切り替えることになります。
<?php
// 地方
$region = get_json( "./region.json" );
// 都道府県
$pref = get_json( "./pref.json" );
// 市町村
$city = get_json( "./city.json" );
// 地方 idとslugの変換用
$regions = [];
foreach( $region as $key => $value ){
$regions[ $value["id"] ] = $value;
}
// 都道府県 codeとslugの変換用
$prefs = [];
foreach( $pref as $key => $value ){
if( $value["region"] ){
$prefs[ $value["code"] ] = mb_strtolower( $value["name_en"] );
}
}
//地方
if( $region ){
?>
<ul class="region-list">
<?php
foreach( $region as $key => $value ){
?>
<li class="region-list__item js-region" data-region="<?php echo $value["name_en"]; ?>"><?php echo $value["name"]; ?></li>
<?php
}
?>
</ul>
<?php
}
?>
<?php
//都道府県
if( $pref ){
?>
<ul class="pref-list">
<?php
foreach( $pref as $key => $value ){
if( $value["region"] ){
?>
<li class="pref-list__item js-pref" data-region="<?php echo $regions[ $value["region"] ]["name_en"]; ?>" data-pref="<?php echo mb_strtolower( $value["name_en"] ); ?>"><?php echo $value["name"]; ?></li>
<?php
}
}
?>
</ul>
<?php
}
?>
<div class="city-content">
<?php
//市区町村
if( $city ){
foreach( $city as $key => $value ){
?>
<ul class="city-list" data-pref="<?php echo $prefs[ $key ]; ?>">
<?php
foreach( $value as $k => $val ){
?>
<li class="city-list__item"><?php echo $val["name"]; ?></li>
<?php
}
?>
</ul>
<?php
}
}
?>
</div>
data属性については、こちらの記事で解説しています。
データ属性の取得方法(jQuery・JavaScript・CSS)【HTML】
HTMLのdata属性の使い方を知りたいですか?この記事では、data属性の使い方、JavaScript、jQuery、CSSでのdata属性の取得方法を紹介しています。ぜひご覧ください。
CSSを書く
地方-都道府県-市区町村が連動するタブ切り替え (デモ) で使用しているCSSを貼っておきますが、ここは好みのデザインに調整してもらえれば大丈夫です。
選択中のタブに使うclass名を「current」としています。
選択した地方に対応する都道府県のclass名を「active」としています。
.region-list{
display: flex;
width: 100%;
}
.region-list__item{
padding: .25em 1em;
color: #fff;
background: #333;
cursor: pointer;
}
.region-list__item.current{
background: red;
}
.pref-list{
display: flex;
width: 100%;
}
.pref-list__item{
padding: .25em 1em;
color: #fff;
background: #333;
cursor: pointer;
}
.pref-list__item.current{
background: blue;
}
.pref-list__item:not(.active){
display: none;
}
.city-content{
padding: 2em;
width: 100%;
background: repeating-linear-gradient(-45deg,transparent,transparent 5px,#eee 0,#eee 6px);
}
.city-list.current{
display: flex;
flex-flow: row wrap;
}
.city-list:not(.current){
display: none;
}
.city-list__item{
line-height: 2;
}
.city-list__item:not(:last-child):after{
content: "|";
margin: 0 .5em;
}
jQueryを書く
最後にjQueryを指定します。
地方のdata-region属性の値を取得して、都道府県のdata-region属性と一致するものに「.active」が設定されます。
同時にクリックした地方自体に「.current」を設定されます。
都道府県のdata-pref属性の値を取得して、都道府県のdata-pref属性と一致するものに「.current」が設定されます。
同時にクリックした都道府県自体に「.current」を設定されます。
上記の2つの動きを関数にして、読み込んだとき、地方をクリックしたとき、都道府県をクリックしたときに動作するようにします。
地方をクリックしたときには、都道府県の状態はリセットしてactiveの中で最初の都道府県がcurrentになるようにしています。
デモではheadタグにscriptを書いていますが、jsファイルをつくってファイルを分けてもかまいません。
$(function(){
// 最初に読み込んだとき
$( ".region-list__item" ).eq(0).addClass("current");
region_active();
pref_active();
// 地方をクリックしたとき
$(".js-region").on("click",function(){
$(".js-region").removeClass("current");
$(this).addClass("current");
$(".js-pref").removeClass("active");
region_active();
pref_active();
});
// 都道府県をクリックしたとき
$(".js-pref").on("click",function(){
$(".js-pref").removeClass("current");
$(this).addClass("current");
pref_active();
});
// 都道府県の動きの関数
function region_active(){
region = $( ".region-list__item.current" ).data("region");
$( ".pref-list__item:not(.current)" ).removeClass("active");
$( ".pref-list [data-region=" + region + "]" ).addClass("active");
$( ".pref-list__item" ).removeClass("current");
$( ".pref-list__item.active" ).eq(0).addClass("current");
}
// 市区町村の動きの関数
function pref_active(){
pref = $( ".pref-list__item.current" ).data("pref");
$( ".city-list" ).removeClass("current");
$( ".city-content [data-pref=" + pref + "]" ).addClass("current");
}
});
まとめ
地方-都道府県-市区町村が連動するタブ切り替えについて解説しました。
- jsonファイルを作成・編集する
- jsonファイルからPHPファイルにHTMLを書き出す
- CSSを書く
- jQueryを書く
jQueryでやっていることはそれほど難しいことではありません。
もう少しスマートのやり方もあると思いますが、とりあえずはHTMLをコピペしてしまえばPHPの知識がなくても動作は実現できます。