【備忘録：HTML、CSS、jQuery】連想配列

# 都道府県表示を連想配列に
セレクトボックスで都道府県を表示させる対応がありましたので、それの備忘録を載せます。
## 完成図
まず以下のような「地域」、「都道府県」を選択できるセレクトボックスがあります。
![スクリーンショット 2020-06-17 11.00.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625199/0819897b-c55d-e455-4bdb-bb3dfa9bb684.png)

「地域」をクリックすると各地域が表示され、どれかを選択すると、
![スクリーンショット 2020-06-17 11.00.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625199/bc9ca0e9-9378-a1e7-f75e-7683864b3934.png)

選択した「地域」の1番目が「都道府県」に表示されるようになっています。
![スクリーンショット 2020-06-17 11.00.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625199/af4d8c81-2ef7-4323-b204-a5b32ac8e45f.png)

「地域」を選択すれば、その地域に沿った「都道府県」が選択できるような動きです。
![スクリーンショット 2020-06-17 11.00.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625199/7eb6219b-ca8f-d6f1-69c1-2da250616ba0.png)

## ソース
全部は載せれないので一部を記載します。

**「地域はHTML側に入力」**し、「都道府県」はjQueryにて呼び出すようにしました。

```html:select.html
<select name="area" id="area">
  <option value="none" selected>地域を選択</option>
  <option value="hokkaido">北海道</option>
  <option value="tohoku">東北</option>
  <option value="hokuriku">北陸</option>
  <option value="kanto">関東</option>
  <option value="chubu">中部</option>
  <option value="kansai">関西</option>
  <option value="shikoku">四国</option>
  <option value="chugoku">中国</option>
  <option value="kyushu">九州</option>
</select>
<select name="pref" id="pref">
  <option value="none" selected>都道府県を選択</option>
</select>
```
jQueryのソースは以下になります。

```javascript:select.js
let $area = $('#area');
let $pref = $('#pref');
let $selectAreaValue = $('#area').find('option:selected').val();//地域選択の値取得
let $selectPrefValue = $('#pref').find('option:selected').val();//都道府県選択の値取得

let $arrayPref = {//①連想配列で都道県を準備。「地域」のvalue値から引っ張れるように。
    'hokkaido':['北海道',['北海道']],
    'tohoku':['東北',['青森','秋田','山形','岩手','宮城','福島']],
    'hokuriku':['北陸',['新潟','富山','石川','福井']],
    'kanto':['関東',['栃木','茨木','群馬','長野','山梨','埼玉','東京','千葉','神奈川']],
    'chubu':['中部',['愛知','岐阜','静岡']],
    'kansai':['関西',['大阪','京都','滋賀','奈良','和歌山','兵庫','三重']],
    'shikoku':['四国',['徳島','愛媛','高知','香川']],
    'chugoku':['中国',['岡山','広島','鳥取','島根','山口']],
    'kyushu':['九州',['福岡','佐賀','長崎','大分','熊本','宮崎','鹿児島','沖縄']]
};

$area.on('change', function(){
  let $this = $(this);
  let $select = $this.find('option:selected');
  $('[data-label="area"]').text($select.text());

  let $val = $('option:selected').val();//②セレクトのvalueを取得
  $pref.children().remove();//③前の選択結果が残るので、セレクトボックスを削除

  let $selectDefault = '<option value="none">都道府県を選択</option>';
  $pref.append($selectDefault);//④初期値に戻す用に、value値noneを先頭に追加

  if($val !== 'none'){//⑤地域選択が、「地域を選択」でなければ、
    $($arrayPref[$val][1]).each(function(num,elem){//セレクトした都道府県配列を回す
    let $selectAppend =  '<option value="' + $arrayPref[$val][1][num] +'">' + $arrayPref[$val][1][num] + '</option>';
    $pref.append($selectAppend);
    //セレクトボックスの地域に合わせて、都道府県のセレクトボックスを追加
    });
  }

  $pref.children().eq(1).prop("selected", true);//⑥地域選択後、その地域の2番目の都道府県を選択させる
});
```

## 解説
### ①連想配列で都道県を準備。「地域」のvalue値から引っ張れるように。
```javascript:select.js
let $arrayPref = {//①連想配列で都道県を準備。「地域」のvalue値から引っ張れるように。
    'hokkaido':['北海道',['北海道']],
    'tohoku':['東北',['青森','秋田','山形','岩手','宮城','福島']],
    'hokuriku':['北陸',['新潟','富山','石川','福井']],
    'kanto':['関東',['栃木','茨木','群馬','長野','山梨','埼玉','東京','千葉','神奈川']],
    'chubu':['中部',['愛知','岐阜','静岡']],
    'kansai':['関西',['大阪','京都','滋賀','奈良','和歌山','兵庫','三重']],
    'shikoku':['四国',['徳島','愛媛','高知','香川']],
    'chugoku':['中国',['岡山','広島','鳥取','島根','山口']],
    'kyushu':['九州',['福岡','佐賀','長崎','大分','熊本','宮崎','鹿児島','沖縄']]
};
```
ここは「地域」選択のセレクトボックスのvalue値から、各地域に沿った都道府県を引っ張れるように連想配列にしています。
各キーの0番目は**「地域」**、1番目は**「地域に沿った都道府県」**ということになります。
例として、
**「tohokuの1番目の1番目は秋田」**
という感じに引っ張ってくるイメージです。

### ②セレクトのvalueを取得、③前の選択結果が残るので、セレクトボックスを削除、④初期値に戻す用に、value値noneを先頭に追加
```javascript:select.js
  let $val = $('option:selected').val();//②セレクトのvalueを取得
  $pref.children().remove();//③前の選択結果が残るので、セレクトボックスを削除

  let $selectDefault = '<option value="none">都道府県を選択</option>';
  $pref.append($selectDefault);//④初期値に戻す用に、value値noneを先頭に追加
```
ここは、②で「地域」で選択したセレクトボックスのvalue値を取得します。
そうすることで、「hokkaido」、「kanto」などの値が取れます。

③は最終的に「都道府県」表示させるのですが、
**2回目以降の「地域」選択時に「都道府県」セレクトボックスに前回の選択地域の都道府県が残ってしまう。**
が発生したので、それを消すために入れてます。
![スクリーンショット 2020-06-17 11.22.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625199/2571ef3b-7530-79c0-46fe-90779df83b42.png)
上記のように北海道を選択後に、東北を選択すると、
![スクリーンショット 2020-06-17 11.22.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625199/7e9dd9d8-7ffb-0c4d-d8d0-9e312ad04313.png)
以前選択した、北海道などが残ってしまうのでそれを回避するための処理です。

④は「都道府県を選択」のセレクトが表示されなくなるのを防ぐため、
**「都道府県」のセレクトボックス先頭に配置**
させるために入れてます。
おそらく地域を選んで、都道府県を選択しないということはないと思いますが、ユーザビリティを考えての配置です。


### ⑤地域選択が、「地域を選択」でなければ、地域に合わせた都道府県のoptionタグを出力
```javascript:select.js
if($val !== 'none'){//⑤地域選択が、「地域を選択」でなければ、
    $($arrayPref[$val][1]).each(function(num,elem){//セレクトした都道府県配列を回す
    let $selectAppend =  '<option value="' + $arrayPref[$val][1][num] +'">' + $arrayPref[$val][1][num] + '</option>';
    $pref.append($selectAppend);
    //セレクトボックスの地域に合わせて、都道府県のセレクトボックスを追加
    });
  }
```
ここで地域に合わせた都道府県をoptionタグで吐き出しています。
また、前述の③、④をやっているので、2回目以降選択しても地域に沿った都道府県のみがでるようになりました。

### ⑥地域選択後、その地域の2番目の都道府県を選択させる
```javascript:select.js
  $pref.children().eq(1).prop("selected", true);//⑥地域選択後、その地域の2番目の都道府県を選択させる
```
⑤の状態ですと、一番上に配置する**「都道府県を選択」**が選択された状態になりますので、
**2番目のopitionタグをselectedにする**
ということを行っています。

## これにて完成
今回value値を引っ張るなどは行わない形だったので、この連想配列でいけましたが、
value値を引っ張るのであれば、ローマ字の都道府県値をvalue値に入れれるような配列に変更する必要があります。