vue.jsを使って都道府県の選択で市区町村のセレクトメニュー値をフィルターする

環境

vue.js :

bootstrap : 3.3.7

 

はじめに

非常にお久しぶりな感じになってしまいました。

ブログの記事を途中まで書いては、下書き保存で放置する日々が続いていました。

今回はvue.jsを使って、選択した都道府県によって、市区町村のセレクトメニューの中身を差し替えるというのをやってみたいと思います。

 

 

都道府県のセレクトメニューを表示する

まず初めに都道府県の内容をセレクトメニューに表示したいと思います。

vue.jsのリストの機能を使って表示してみます。

■リストレンダリング
https://jp.vuejs.org/v2/guide/list.html

 

■HTML


<table id="Vueshop" class="table">
<tr>
<th>都道府県</th> 
<td>
      <select id="shop_pref" name="input_pref" class="form-control input-lg">
         <option value="">都道府県選択</option>
         <option v-for="(item, index) in getPref" v-bind:value="item.no">{{item.name}}</option>
      </select>
    </td>
  </tr>
</table>

 

■javascript

var SHOP =  new Vue({
        el: '#Vueshop',
        data: {
                 pref: [{"no":"1","name":"\u5317\u6d77\u9053"},{"no":"2","name":"\u9752\u68ee\u770c"},{"no":"3","name":"\u5ca9\u624b\u770c"},{"no":"4","name":"\u5bae\u57ce\u770c"},{"no":"5","name":"\u79cb\u7530\u770c"},{"no":"6","name":"\u5c71\u5f62\u770c"},{"no":"7","name":"\u798f\u5cf6\u770c"},{"no":"8","name":"\u8328\u57ce\u770c"},{"no":"9","name":"\u6803\u6728\u770c"},{"no":"10","name":"\u7fa4\u99ac\u770c"},{"no":"11","name":"\u57fc\u7389\u770c"},{"no":"12","name":"\u5343\u8449\u770c"},{"no":"13","name":"\u6771\u4eac\u90fd"},{"no":"14","name":"\u795e\u5948\u5ddd\u770c"},{"no":"15","name":"\u65b0\u6f5f\u770c"},{"no":"16","name":"\u5bcc\u5c71\u770c"},{"no":"17","name":"\u77f3\u5ddd\u770c"},{"no":"18","name":"\u798f\u4e95\u770c"},{"no":"19","name":"\u5c71\u68a8\u770c"},{"no":"20","name":"\u9577\u91ce\u770c"},{"no":"21","name":"\u5c90\u961c\u770c"},{"no":"22","name":"\u9759\u5ca1\u770c"},{"no":"23","name":"\u611b\u77e5\u770c"},{"no":"24","name":"\u4e09\u91cd\u770c"},{"no":"25","name":"\u6ecb\u8cc0\u770c"},{"no":"26","name":"\u4eac\u90fd\u5e9c"},{"no":"27","name":"\u5927\u962a\u5e9c"},{"no":"28","name":"\u5175\u5eab\u770c"},{"no":"29","name":"\u5948\u826f\u770c"},{"no":"30","name":"\u548c\u6b4c\u5c71\u770c"},{"no":"31","name":"\u9ce5\u53d6\u770c"},{"no":"32","name":"\u5cf6\u6839\u770c"},{"no":"33","name":"\u5ca1\u5c71\u770c"},{"no":"34","name":"\u5e83\u5cf6\u770c"},{"no":"35","name":"\u5c71\u53e3\u770c"},{"no":"36","name":"\u5fb3\u5cf6\u770c"},{"no":"37","name":"\u9999\u5ddd\u770c"},{"no":"38","name":"\u611b\u5a9b\u770c"},{"no":"39","name":"\u9ad8\u77e5\u770c"},{"no":"40","name":"\u798f\u5ca1\u770c"},{"no":"41","name":"\u4f50\u8cc0\u770c"},{"no":"42","name":"\u9577\u5d0e\u770c"},{"no":"43","name":"\u718a\u672c\u770c"},{"no":"44","name":"\u5927\u5206\u770c"},{"no":"45","name":"\u5bae\u5d0e\u770c"},{"no":"46","name":"\u9e7f\u5150\u5cf6\u770c"},{"no":"47","name":"\u6c96\u7e04\u770c"}]
        },
        computed: {
            getPref: {
                get: function () {
                    var self = this;
                    return self.pref.filter(function (item) {
                        return item;
                    });
                },
                set: function (v) {
                    this.pref = v;
                }
            }
        }
    });

都道府県のJsonのデータが文字化けているように見えますが、これはJsonをUnicodeで変換しているからです。
PHPを使っているのであれば、json_encodeなんかを使うと配列をJsonに変換して、Unicode変換を行ってくれるはずです。

■json_encode
http://php.net/manual/ja/function.json-encode.php

 

■サンプルデータ

json_encode(array(array('no'=>1, 'name'=>'北海道'),array('no'=>2, 'name'=>'青森県'),array('no'=>3, 'name'=>'岩手県'),array('no'=>4, 'name'=>'宮城県'),array('no'=>5, 'name'=>'秋田県'),array('no'=>6, 'name'=>'山形県'),array('no'=>7, 'name'=>'福島県'),array('no'=>8, 'name'=>'茨城県'),array('no'=>9, 'name'=>'栃木県'),array('no'=>10, 'name'=>'群馬県'),array('no'=>11, 'name'=>'埼玉県'),array('no'=>12, 'name'=>'千葉県'),array('no'=>13, 'name'=>'東京都'),array('no'=>14, 'name'=>'神奈川県'),array('no'=>15, 'name'=>'新潟県'),array('no'=>16, 'name'=>'富山県'),array('no'=>17, 'name'=>'石川県'),array('no'=>18, 'name'=>'福井県'),array('no'=>19, 'name'=>'山梨県'),array('no'=>20, 'name'=>'長野県'),array('no'=>21, 'name'=>'岐阜県'),array('no'=>22, 'name'=>'静岡県'),array('no'=>23, 'name'=>'愛知県'),array('no'=>24, 'name'=>'三重県'),array('no'=>25, 'name'=>'滋賀県'),array('no'=>26, 'name'=>'京都府'),array('no'=>27, 'name'=>'大阪府'),array('no'=>28, 'name'=>'兵庫県'),array('no'=>29, 'name'=>'奈良県'),array('no'=>30, 'name'=>'和歌山県'),array('no'=>31, 'name'=>'鳥取県'),array('no'=>32, 'name'=>'島根県'),array('no'=>33, 'name'=>'岡山県'),array('no'=>34, 'name'=>'広島県'),array('no'=>35, 'name'=>'山口県'),array('no'=>36, 'name'=>'徳島県'),array('no'=>37, 'name'=>'香川県'),array('no'=>38, 'name'=>'愛媛県'),array('no'=>39, 'name'=>'高知県'),array('no'=>40, 'name'=>'福岡県'),array('no'=>41, 'name'=>'佐賀県'),array('no'=>42, 'name'=>'長崎県'),array('no'=>43, 'name'=>'熊本県'),array('no'=>44, 'name'=>'大分県'),array('no'=>45, 'name'=>'宮崎県'),array('no'=>46, 'name'=>'鹿児島県'),array('no'=>47, 'name'=>'沖縄県')));

See the Pen jGQLeY by カバの樹 (@kabanoki) on CodePen.0

 

 

市区町村のセレクトメニューを表示する

次に都道府県と同じように市区町村のメニューを追加します。

 

■HTML


<table id="Vueshop" class="table">
<tr>
<th>都道府県</th>
<td>
    <select id="shop_pref" name="input_pref" class="form-control input-lg">
         <option value="">都道府県選択</option>
         <option v-for="(item, index) in getPref" v-bind:value="item.no">{{item.name}}</option>
      </select>
    </td>
  </tr>  
<tr>    
<th>市区町村</th>    
<td>
      <select id="shop_city" name="input_city" class="form-control input-lg" >
         <option value="" >市選択</option>
         <option v-for="(item, index) in getCity" v-bind:value="item.no">{{item.name}}</option>
     </select>
    </td>
  </tr>
</table>

 

■javascript

var SHOP =  new Vue({
        el: '#Vueshop',
        data: {
             pref: [{"no":"1","name":"\u5317\u6d77\u9053"},{"no":"2","name":"\u9752\u68ee\u770c"},{"no":"3","name":"\u5ca9\u624b\u770c"},{"no":"4","name":"\u5bae\u57ce\u770c"},{"no":"5","name":"\u79cb\u7530\u770c"},{"no":"6","name":"\u5c71\u5f62\u770c"},{"no":"7","name":"\u798f\u5cf6\u770c"},{"no":"8","name":"\u8328\u57ce\u770c"},{"no":"9","name":"\u6803\u6728\u770c"},{"no":"10","name":"\u7fa4\u99ac\u770c"},{"no":"11","name":"\u57fc\u7389\u770c"},{"no":"12","name":"\u5343\u8449\u770c"},{"no":"13","name":"\u6771\u4eac\u90fd"},{"no":"14","name":"\u795e\u5948\u5ddd\u770c"},{"no":"15","name":"\u65b0\u6f5f\u770c"},{"no":"16","name":"\u5bcc\u5c71\u770c"},{"no":"17","name":"\u77f3\u5ddd\u770c"},{"no":"18","name":"\u798f\u4e95\u770c"},{"no":"19","name":"\u5c71\u68a8\u770c"},{"no":"20","name":"\u9577\u91ce\u770c"},{"no":"21","name":"\u5c90\u961c\u770c"},{"no":"22","name":"\u9759\u5ca1\u770c"},{"no":"23","name":"\u611b\u77e5\u770c"},{"no":"24","name":"\u4e09\u91cd\u770c"},{"no":"25","name":"\u6ecb\u8cc0\u770c"},{"no":"26","name":"\u4eac\u90fd\u5e9c"},{"no":"27","name":"\u5927\u962a\u5e9c"},{"no":"28","name":"\u5175\u5eab\u770c"},{"no":"29","name":"\u5948\u826f\u770c"},{"no":"30","name":"\u548c\u6b4c\u5c71\u770c"},{"no":"31","name":"\u9ce5\u53d6\u770c"},{"no":"32","name":"\u5cf6\u6839\u770c"},{"no":"33","name":"\u5ca1\u5c71\u770c"},{"no":"34","name":"\u5e83\u5cf6\u770c"},{"no":"35","name":"\u5c71\u53e3\u770c"},{"no":"36","name":"\u5fb3\u5cf6\u770c"},{"no":"37","name":"\u9999\u5ddd\u770c"},{"no":"38","name":"\u611b\u5a9b\u770c"},{"no":"39","name":"\u9ad8\u77e5\u770c"},{"no":"40","name":"\u798f\u5ca1\u770c"},{"no":"41","name":"\u4f50\u8cc0\u770c"},{"no":"42","name":"\u9577\u5d0e\u770c"},{"no":"43","name":"\u718a\u672c\u770c"},{"no":"44","name":"\u5927\u5206\u770c"},{"no":"45","name":"\u5bae\u5d0e\u770c"},{"no":"46","name":"\u9e7f\u5150\u5cf6\u770c"},{"no":"47","name":"\u6c96\u7e04\u770c"}],
            city: [{"no":"4","name":"\u5ddd\u5d0e\u5e02","pref":"14","prefName":"\u795e\u5948\u5ddd\u770c"},{"no":"5","name":"\u8c4a\u5cf6\u533a","pref":"13","prefName":"\u6771\u4eac\u90fd"},{"no":"6","name":"\u6a2a\u6d5c\u5e02","pref":"14","prefName":"\u795e\u5948\u5ddd\u770c"},{"no":"7","name":"\u8239\u6a4b\u5e02","pref":"12","prefName":"\u5343\u8449\u770c"},{"no":"8","name":"\u677e\u5c71\u5e02","pref":"23","prefName":"\u611b\u77e5\u770c"},{"no":"9","name":"\u8c4a\u6a4b\u5e02","pref":"23","prefName":"\u611b\u77e5\u770c"},{"no":"10","name":"\u540d\u53e4\u5c4b\u5e02","pref":"23","prefName":"\u611b\u77e5\u770c"},{"no":"11","name":"\u679a\u65b9\u5e02","pref":"27","prefName":"\u5927\u962a\u5e9c"},{"no":"12","name":"\u677e\u5c71\u5e02","pref":"38","prefName":"\u611b\u5a9b\u770c"}],
        },
        computed: {
            getPref: {
                get: function () {
                    var self = this;
                    return self.pref.filter(function (item) {
                        return item;
                    });
                },
                set: function (v) {
                    this.pref = v;
                }
            },
            getCity: {
                get: function () {
                    var self = this;
                    return self.city.filter(function (item) {
                        return item;
                    });
                },
                set: function (v) {
                    this.city = v;
                }
            },
        }
    });

 

■サンプルデータ

json_encode(array(array('no'=>4, 'name'=>'川崎市', 'pref'=>14, 'prefName'=>'神奈川県'),array('no'=>5, 'name'=>'豊島区', 'pref'=>13, 'prefName'=>'東京都'),array('no'=>6, 'name'=>'横浜市', 'pref'=>14, 'prefName'=>'神奈川県'),array('no'=>7, 'name'=>'船橋市', 'pref'=>12, 'prefName'=>'千葉県'),array('no'=>8, 'name'=>'松山市', 'pref'=>23, 'prefName'=>'愛知県'),array('no'=>9, 'name'=>'豊橋市', 'pref'=>23, 'prefName'=>'愛知県'),array('no'=>10, 'name'=>'名古屋市', 'pref'=>23, 'prefName'=>'愛知県'),array('no'=>11, 'name'=>'枚方市', 'pref'=>27, 'prefName'=>'大阪府'),array('no'=>12, 'name'=>'松山市', 'pref'=>38, 'prefName'=>'愛媛県')));

 

See the Pen PJxKxW by カバの樹 (@kabanoki) on CodePen.0

 

 

選択した都道府県に合わせて市区町村のセレクトメニューを絞り込む

最後に都道府県で選択した値によって、市区町村の値をフィルタリングして表示します。

vueにはフィルタリングをする機能もあるのでとっても便利です。

■フィルター
https://jp.vuejs.org/v2/guide/list.html#フィルタ-ソートされた結果の表示
フィルターをするついでに、都道府県を選択しないと市区町村が選択できなくします。
 

■HTML


<table id="Vueshop" class="table">  
<tr>    
<th>都道府県</th>    
<td>
      <select id="shop_pref" name="input_pref" v-model="selectPref" class="form-control input-lg">
         <option value="">都道府県選択</option>
         <option v-for="(item, index) in getPref" v-bind:value="item.no">{{item.name}}</option>
      </select>
    </td>
  </tr>  
<tr>    
<th>市区町村</th>    
<td>
      <select id="shop_city" name="input_city" v-model="selectCity" class="form-control input-lg" v-bind:disabled="selectPref == ''">
         <option value="" >市選択</option>
         <option v-for="(item, index) in getCity" v-bind:value="item.no">{{item.name}}</option>
      </select>
    </td>
  </tr>
</table>

 

■javascript

var SHOP =  new Vue({
        el: '#Vueshop',
        data: {
             pref: [{"no":"1","name":"\u5317\u6d77\u9053"},{"no":"2","name":"\u9752\u68ee\u770c"},{"no":"3","name":"\u5ca9\u624b\u770c"},{"no":"4","name":"\u5bae\u57ce\u770c"},{"no":"5","name":"\u79cb\u7530\u770c"},{"no":"6","name":"\u5c71\u5f62\u770c"},{"no":"7","name":"\u798f\u5cf6\u770c"},{"no":"8","name":"\u8328\u57ce\u770c"},{"no":"9","name":"\u6803\u6728\u770c"},{"no":"10","name":"\u7fa4\u99ac\u770c"},{"no":"11","name":"\u57fc\u7389\u770c"},{"no":"12","name":"\u5343\u8449\u770c"},{"no":"13","name":"\u6771\u4eac\u90fd"},{"no":"14","name":"\u795e\u5948\u5ddd\u770c"},{"no":"15","name":"\u65b0\u6f5f\u770c"},{"no":"16","name":"\u5bcc\u5c71\u770c"},{"no":"17","name":"\u77f3\u5ddd\u770c"},{"no":"18","name":"\u798f\u4e95\u770c"},{"no":"19","name":"\u5c71\u68a8\u770c"},{"no":"20","name":"\u9577\u91ce\u770c"},{"no":"21","name":"\u5c90\u961c\u770c"},{"no":"22","name":"\u9759\u5ca1\u770c"},{"no":"23","name":"\u611b\u77e5\u770c"},{"no":"24","name":"\u4e09\u91cd\u770c"},{"no":"25","name":"\u6ecb\u8cc0\u770c"},{"no":"26","name":"\u4eac\u90fd\u5e9c"},{"no":"27","name":"\u5927\u962a\u5e9c"},{"no":"28","name":"\u5175\u5eab\u770c"},{"no":"29","name":"\u5948\u826f\u770c"},{"no":"30","name":"\u548c\u6b4c\u5c71\u770c"},{"no":"31","name":"\u9ce5\u53d6\u770c"},{"no":"32","name":"\u5cf6\u6839\u770c"},{"no":"33","name":"\u5ca1\u5c71\u770c"},{"no":"34","name":"\u5e83\u5cf6\u770c"},{"no":"35","name":"\u5c71\u53e3\u770c"},{"no":"36","name":"\u5fb3\u5cf6\u770c"},{"no":"37","name":"\u9999\u5ddd\u770c"},{"no":"38","name":"\u611b\u5a9b\u770c"},{"no":"39","name":"\u9ad8\u77e5\u770c"},{"no":"40","name":"\u798f\u5ca1\u770c"},{"no":"41","name":"\u4f50\u8cc0\u770c"},{"no":"42","name":"\u9577\u5d0e\u770c"},{"no":"43","name":"\u718a\u672c\u770c"},{"no":"44","name":"\u5927\u5206\u770c"},{"no":"45","name":"\u5bae\u5d0e\u770c"},{"no":"46","name":"\u9e7f\u5150\u5cf6\u770c"},{"no":"47","name":"\u6c96\u7e04\u770c"}],
            city: [{"no":"4","name":"\u5ddd\u5d0e\u5e02","pref":"14","prefName":"\u795e\u5948\u5ddd\u770c"},{"no":"5","name":"\u8c4a\u5cf6\u533a","pref":"13","prefName":"\u6771\u4eac\u90fd"},{"no":"6","name":"\u6a2a\u6d5c\u5e02","pref":"14","prefName":"\u795e\u5948\u5ddd\u770c"},{"no":"7","name":"\u8239\u6a4b\u5e02","pref":"12","prefName":"\u5343\u8449\u770c"},{"no":"8","name":"\u677e\u5c71\u5e02","pref":"23","prefName":"\u611b\u77e5\u770c"},{"no":"9","name":"\u8c4a\u6a4b\u5e02","pref":"23","prefName":"\u611b\u77e5\u770c"},{"no":"10","name":"\u540d\u53e4\u5c4b\u5e02","pref":"23","prefName":"\u611b\u77e5\u770c"},{"no":"11","name":"\u679a\u65b9\u5e02","pref":"27","prefName":"\u5927\u962a\u5e9c"},{"no":"12","name":"\u677e\u5c71\u5e02","pref":"38","prefName":"\u611b\u5a9b\u770c"}],
            selectPref: '',
            selectCity: '',
        },
        computed: {
            getPref: {
                get: function () {
                    var self = this;
                    return self.pref.filter(function (item) {
                        return item;
                    });
                },
                set: function (v) {
                    this.pref = v;
                }
            },
            getCity: {
                get: function () {
                    var self = this;
                    return self.city.filter(function (item) {
                        return (item.pref.indexOf(self.selectPref) !== -1 && (item.pref == self.selectPref || self.selectPref == ''));
                    });
                },
                set: function (v) {
                    this.city = v;
                }
            },
        },
        watch: {
            selectPref: function(newValue) {
                this.selectCity = '';
            }
        }
    });

 

See the Pen pWQrLa by カバの樹 (@kabanoki) on CodePen.0

  • この記事を書いた人

カバノキ

印刷会社のWEB部隊に所属してます。 WEB制作に携わってから、もう時期10年になります。 普段の業務では、PHPをメインにサーバーサイドの言語を扱っています。 最近のお気に入りはJavascriptです。 Vue.jsを狂喜乱舞しながら、社内に布教中です。

-vue.js
-, , , , ,