勉強したことのメモ

Webエンジニア / プログラマが勉強したことのメモ。

八地方区分→都道府県→路線→駅名の連携したセレクトメニュー の実装方法

   2024/02/20  jQuery JavaScript

八地方区分(関東、近畿等)をプルダウンから選ぶと区分内の都道府県プルダウンが表示され、さらに都道府県を選ぶと路線が、路線を選ぶと駅名が選択できるといった一連のセレクトメニューを作成したかった。あと路線を選択する際はJR / 私鉄 / 地下鉄の3つのセレクトメニューに分けたかった。以下に方法をメモ。

 

路線図や駅名のデータ

CSVファイルのダウンロード

以下サイトからCSVファイルをダウンロードする。今回必要になるのは事業者データ、路線データ、駅データになる。

http://www.ekidata.jp/dl/

CSVファイル内の仕様について

データ仕様は以下ページを参照。

http://www.ekidata.jp/doc/

CSVファイルをMySQLにインポート

CSVファイル一行目と同じカラムを設定したテーブルを作成し、以下のような形でデータを取り込む。

LOAD DATA LOCAL INFILE "/var/www/html/hoge/station.csv" INTO TABLE `station` FIELDS TERMINATED BY ',' IGNORE 1 LINES;

JR or 私鉄の判別について

事業者データでJR or 私鉄は判断できるが地下鉄かどうかは判断できなかったのでsubwayカラム(int)を作成し、以下ページを参考の上で地下鉄の場合は1を、その他は0の値を入れた。16件だけなのですぐ対応できる。

https://ja.wikipedia.org/wiki/%E5%9C%B0%E4%B8%8B%E9%89%84%E4%B8%80%E8%A6%A7

 

都道府県と八地方区分データ

以下でadminer等からデータを突っ込む。

CREATE TABLE `region` (
    `id` tinyint(3) unsigned NOT NULL,
    `name` varchar(255) DEFAULT NULL,
    `name_kana` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`id`)
);

CREATE TABLE `prefecture` (
    `id` tinyint(3) unsigned NOT NULL,
    `region_id` tinyint(3) DEFAULT NULL,
    `name` varchar(255) DEFAULT NULL,
    `name_kana` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`id`)
);

INSERT INTO 
`region` VALUES
(1,'北海道地方','ホッカイドウチホウ'),
(2,'東北地方','トウホクチホウ'),
(3,'関東地方','カントウチホウ'),
(4,'中部地方','チュウブチホウ'),
(5,'近畿地方','キンキチホウ'),
(6,'中国地方','チュウゴクチホウ'),
(7,'四国地方','シコクチホウ'),
(8,'九州地方','キュウシュウチホウ');

INSERT INTO `prefecture` VALUES
(1,1,'北海道','ホッカイドウ'),
(2,2,'青森県','アオモリケン'),
(3,2,'岩手県','イワテケン'),
(4,2,'宮城県','ミヤギケン'),
(5,2,'秋田県','アキタケン'),
(6,2,'山形県','ヤマガタケン'),
(7,2,'福島県','フクシマケン'),
(8,3,'茨城県','イバラキケン'),
(9,3,'栃木県','トチギケン'),
(10,3,'群馬県','グンマケン'),
(11,3,'埼玉県','サイタマケン'),
(12,3,'千葉県','チバケン'),
(13,3,'東京都','トウキョウト'),
(14,3,'神奈川県','カナガワケン'),
(15,4,'新潟県','ニイガタケン'),
(16,4,'富山県','トヤマケン'),
(17,4,'石川県','イシカワケン'),
(18,4,'福井県','フクイケン'),
(19,4,'山梨県','ヤマナシケン'),
(20,4,'長野県','ナガノケン'),
(21,4,'岐阜県','ギフケン'),
(22,4,'静岡県','シズオカケン'),
(23,4,'愛知県','アイチケン'),
(24,5,'三重県','ミエケン'),
(25,5,'滋賀県','シガケン'),
(26,5,'京都府','キョウトフ'),
(27,5,'大阪府','オオサカフ'),
(28,5,'兵庫県','ヒョウゴケン'),
(29,5,'奈良県','ナラケン'),
(30,5,'和歌山県','ワカヤマケン'),
(31,6,'鳥取県','トットリケン'),
(32,6,'島根県','シマネケン'),
(33,6,'岡山県','オカヤマケン'),
(34,6,'広島県','ヒロシマケン'),
(35,6,'山口県','ヤマグチケン'),
(36,7,'徳島県','トクシマケン'),
(37,7,'香川県','カガワケン'),
(38,7,'愛媛県','エヒメケン'),
(39,7,'高知県','コウチケン'),
(40,8,'福岡県','フクオカケン'),
(41,8,'佐賀県','サガケン'),
(42,8,'長崎県','ナガサキケン'),
(43,8,'熊本県','クマモトケン'),
(44,8,'大分県','オオイタケン'),
(45,8,'宮崎県','ミヤザキケン'),
(46,8,'鹿児島県','カゴシマケン'),
(47,8,'沖縄県','オキナワケン');

 

ajax受信用プログラム

<?php
#データベース接続しておく

$mode = $_POST['mode'];

$result = false;

if( $mode == 'region' && $_POST['id'] ){
    $sql = '
        SELECT * 
        FROM prefecture 
        WHERE region_id = "' . $mysqli->real_escape_string($_POST['id']) . '"
    ';
    $row = $mysqli->query($sql);
    while ($rs = $row->fetch_array(MYSQLI_ASSOC)) {
        $result[] = $rs;
    }


}else if( $mode == 'prefecture' && $_POST['id'] ){
    $sql = '
        SELECT 
            c.company_cd, c.company_name, c.company_name_r, c.company_type, c.subway, 
            l.line_name, l.line_cd, 
            s.pref_cd 
        FROM company AS c 
        LEFT JOIN line AS l 
        ON c.company_cd = l.company_cd
        LEFT JOIN station AS s 
        ON l.line_cd = s.line_cd 
        WHERE s.e_status = 0 
        AND l.e_status = 0 
        AND s.e_status = 0 
        AND s.pref_cd = "' . $mysqli->real_escape_string($_POST['id']) . '" 
        GROUP BY l.line_name
    ';
    $row = $mysqli->query($sql);
    while ($rs = $row->fetch_array(MYSQLI_ASSOC)) {
        $result[] = $rs;
    }


}else if( $mode == 'station' && $_POST['id'] ){
    $sql = '
        SELECT * 
        FROM station 
        WHERE line_cd = "' . $mysqli->real_escape_string($_POST['id']) . '" 
        AND e_status = 0 
    ';
    $row = $mysqli->query($sql);
    while ($rs = $row->fetch_array(MYSQLI_ASSOC)) {
        $result[] = $rs;
    }
}


if( $result ){
    echo json_encode($result);
}

 

ajax送信用プログラム

<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>test</title>
</head>
<body>

    <h2>エリア</h2>

    <div>
        <p>八地方区分</p>
        <select name="region" id="region">
            <option value="1">北海道地方</option>
            <option value="2">東北地方</option>
            <option value="3">関東地方</option>
            <option value="4">中部地方</option>
            <option value="5">近畿地方</option>
            <option value="6">中国地方</option>
            <option value="7">四国地方</option>
            <option value="8">九州地方</option>
        </select>
    </div>

    <div>
        <p>都道府県</p>
        <select name="prefecture" id="prefecture">
        </select>
    </div>

    <hr>

    <h2>路線</h2>

    <div>
        <p>地下鉄</p>
        <select name="subway" id="subway">
        </select>
    </div>


    <div>
        <p>私鉄</p>
        <select name="private" id="private">
        </select>
    </div>

    <div>
        <p>JR</p>
        <select name="jr" id="jr">
        </select>
    </div>

    <hr>

    <h2>駅名</h2>

    <div>
        <p>駅名</p>
        <select name="station" id="station">
        </select>
    </div>

    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script>
    $(function(){
        var api = '//hogehoge.com/api.php';

        //八地方区分変更
        $('#region').change(function(){
            var data = { mode : 'region', id : $(this).val() };
            $.ajax({
                type: "POST",
                url: api,
                data: data,
                success: function(result){
                    if(result){
                        var prefecture = $.parseJSON(result);
                        var html = '';
                        for(var key in prefecture){
                            html += '<option value="' + prefecture[key]['id'] + '">' + prefecture[key]['name'] + '</option>';
                        }
                        $('#prefecture').html(html);
                    }else{
                        alert('通信エラーが発生しました。');
                    }
                }
            });
        });

        //都道府県変更
        $('#prefecture').change(function(){
            var data = { mode : 'prefecture', id : $(this).val() };
            $.ajax({
                type: "POST",
                url: api,
                data: data,
                success: function(result){
                    if(result){
                        var line = $.parseJSON(result);
                        var subway = '';
                        var private = '';
                        var jr = '';

                        for(var key in line){
                            if( line[key]['subway'] == 1 ){
                                subway += '<option value="' + line[key]['line_cd'] + '">' + line[key]['line_name'] + '</option>';
                            }else if( line[key]['company_type'] == 1 ){
                                jr += '<option value="' + line[key]['line_cd'] + '">' + line[key]['line_name'] + '</option>';
                            }else{
                                private += '<option value="' + line[key]['line_cd'] + '">' + line[key]['line_name'] + '</option>';
                            }
                            $('#subway').html(subway);
                            $('#private').html(private);
                            $('#jr').html(jr);
                        }
                    }else{
                        alert('通信エラーが発生しました。');
                    }
                }
            });
        });

        //路線変更
        $('#subway, #private, #jr').change(function(){
            var data = { mode : 'station', id : $(this).val() };
            $.ajax({
                type: "POST",
                url: api,
                data: data,
                success: function(result){
                    if(result){
                        var station = $.parseJSON(result);
                        var html = '';
                        for(var key in station){
                            html += '<option value="' + station[key]['station_cd'] + '">' + station[key]['station_name'] + '</option>';
                        }
                        $('#station').html(html);
                    }else{
                        alert('通信エラーが発生しました。');
                    }
                }
            });
        });

    });
    </script>
</body>
</html>

 

その他

駅名と何らかのデータを組み合わせたい場合は受信側で色々すれば対応できそう。

 - jQuery JavaScript

  関連記事

ajaxのエラー詳細を取得する

success or errorで分岐処理はできるけど、 エラー詳細取れないの? ...

jQueryでページ表示時にラジオボタンやチェックボックスにcheckedがついている場合にイベントを実行する方法

ラジオボタンやチェックボックスをチェックした際に、jQuery側で何らかのイベン ...

jQueryのanimate()でページスクロール後に他の処理を実行させる方法

jQueryのanimate()でページスクロール後に特定の要素を非表示にしたい ...

jQueryで特定のdata属性をセレクタとして指定する方法

jQueryで特定のdata属性をクリックした際に何らかのイベントを実行したかっ ...

jQueryでチェックボックスの全チェック&チェック解除する方法

フォームのチェックボックスで「全てにチェックを入れる」「全てのチェックを外す」と ...