<div class="utility-05 p-2" id="js-utility-05">
<div class="field">
<div class="control">
<div class="select is-fullwidth"><select id="js-utility-05-prefecture" name="prefecture" disabled="disabled"></select></div>
</div>
</div>
<div class="field">
<div class="control">
<div class="select is-fullwidth"><select id="js-utility-05-district" name="district" disabled="disabled"></select></div>
</div>
</div>
<div class="field">
<div class="control">
<div class="select is-fullwidth"><select id="js-utility-05-town" name="town" disabled="disabled"></select></div>
</div>
</div>
</div>
#js-utility-05.utility-05.p-2
.field
.control
.select.is-fullwidth
select#js-utility-05-prefecture(name='prefecture', disabled)
.field
.control
.select.is-fullwidth
select#js-utility-05-district(name='district', disabled)
.field
.control
.select.is-fullwidth
select#js-utility-05-town(name='town', disabled)
/* No context defined. */
$BLOCK_NAME: '.utility-05';
// 変数
#{ $BLOCK_NAME } {
//
}
'use strict';
export const utility05 = () => {
const utility = new Utility05('js-utility-05');
utility.init();
}
class Utility05 {
el: HTMLElement;
prefectureEl: HTMLSelectElement;
districtEl: HTMLSelectElement;
townEl: HTMLSelectElement;
prefectureId: string;
districtId: string;
townId: string;
dataUrl: string;
data: any;
constructor(elId: string) {
this.el = document.getElementById(elId);
this.prefectureEl = <HTMLSelectElement>document.getElementById('js-utility-05-prefecture');
this.districtEl = <HTMLSelectElement>document.getElementById('js-utility-05-district');
this.townEl = <HTMLSelectElement>document.getElementById('js-utility-05-town');
this.prefectureId = '';
this.districtId = '';
this.townId = '';
if (location.origin === 'https://zakzakst.github.io') {
// GitHubの場合
this.dataUrl = '/parts/data/utility05.json';
} else {
// ローカル環境の場合
this.dataUrl = '/data/utility05.json';
}
this.data = null;
}
/**
* 初期化
*/
async init(): Promise<void> {
if (!this.el) return;
this.data = await this.loadData();
if (!Object.keys(this.data).length) return;
this.setPrefecture();
this.onChangePrefecture();
this.onChangeDistrict();
}
/**
* データを読み込み
*/
loadData(): Promise<any> {
return new Promise(resolve => {
fetch(this.dataUrl)
.then((res) => {
return res.json();
})
.then((data) => {
resolve(data);
})
.catch(error => {
console.log(error);
resolve({});
});
});
}
/**
* 都道府県を設定
*/
setPrefecture(): void {
const selectItems = [
{
id: '',
label: '選択してください',
},
];
for (let item in this.data) {
const { id, label } = this.data[item];
selectItems.push({
id,
label,
});
}
// HTMLを初期化
this.prefectureEl.innerHTML = '';
// 要素を挿入
let markup = '';
selectItems.forEach(selectItem => {
markup += `<option value="${selectItem.id}">${selectItem.label}</option>`;
});
this.prefectureEl.insertAdjacentHTML('beforeend', markup);
// 選択を有効にする
this.prefectureEl.disabled = null;
}
/**
* 区を設定
*/
setDistrict(): void {
const districtData = this.data[this.prefectureId]?.dists || null;
this.clearDistrict();
// データが空のオブジェクトの場合、選択肢がないことを表示して処理を終了
if (!Object.keys(districtData).length) {
this.districtEl.insertAdjacentHTML('beforeend', '<option value="">区の選択肢はありません</option>');
return;
}
const selectItems = [
{
id: '',
label: '選択してください',
},
];
for (let item in districtData) {
const { id, label } = districtData[item];
selectItems.push({
id,
label,
});
}
// HTMLを初期化
this.districtEl.innerHTML = '';
// 要素を挿入
let markup = '';
selectItems.forEach(selectItem => {
markup += `<option value="${selectItem.id}">${selectItem.label}</option>`;
});
this.districtEl.insertAdjacentHTML('beforeend', markup);
// 選択を有効にする
this.districtEl.disabled = null;
}
/**
* 町を設定
*/
setTown(): void {
const townData = this.data[this.prefectureId]?.dists[this.districtId]?.towns || null;
// データが空のオブジェクトの場合、選択肢がないことを表示して処理を終了
this.clearTown();
if (!Object.keys(townData).length) {
this.townEl.insertAdjacentHTML('beforeend', '<option value="">町の選択肢はありません</option>');
return;
}
const selectItems = [
{
id: '',
label: '選択してください',
},
];
for (let item in townData) {
const { id, label } = townData[item];
selectItems.push({
id,
label,
});
}
// HTMLを初期化
this.townEl.innerHTML = '';
// 要素を挿入
let markup = '';
selectItems.forEach(selectItem => {
markup += `<option value="${selectItem.id}">${selectItem.label}</option>`;
});
this.townEl.insertAdjacentHTML('beforeend', markup);
// 選択を有効にする
this.townEl.disabled = null;
}
/**
* 区をクリア
*/
clearDistrict(): void {
// 町をクリア
this.clearTown();
// HTMLを初期化
this.districtEl.innerHTML = '';
// 選択を無効にする
this.districtEl.disabled = true;
// IDを初期化
this.districtId = '';
}
/**
* 町をクリア
*/
clearTown(): void {
// HTMLを初期化
this.townEl.innerHTML = '';
// 選択を無効にする
this.townEl.disabled = true;
// IDを初期化
this.townId = '';
}
/**
* 都道府県変更時のイベント設定
*/
onChangePrefecture(): void {
this.prefectureEl.addEventListener('change', () => {
this.prefectureId = this.prefectureEl.value;
if (this.prefectureId) {
// IDが設定されている項目の場合、区を設定
this.setDistrict();
} else {
// IDが設定されていない項目の場合、区をクリア
this.clearDistrict();
}
});
}
/**
* 区変更時のイベント設定
*/
onChangeDistrict(): void {
this.districtEl.addEventListener('change', () => {
this.districtId = this.districtEl.value;
if (this.districtId) {
// IDが設定されている項目の場合、町を設定
this.setTown();
} else {
// IDが設定されていない項目の場合、町をクリア
this.clearTown();
}
});
}
}
JSON データ( https://zakzakst.github.io/parts/data/utility05.json )を取得して入力制限するスクリプト。