複数のセレクトボックスに対して、ユーザーが順番に入力を選択するように制御したい。そんなときに使える実装方法のご紹介です。
例えば、「大カテゴリ」「中カテゴリ」…といった条件絞り込みフォームや、「都道府県」→「市区町村」→「町名」のような段階的な住所入力欄などで、このような仕様が必要になる場面があります。
デモ
See the Pen フォームの入力順序を制御する by MEMORUKA (@memoruka) on CodePen.
仕組みと狙い
ユーザーがセレクトボックスを昇順に選択していくように制御し、値が入力されたタイミングでJavaScriptが次のセレクトボックスのdisabled
を解除します。
逆に、入力がクリアされた場合は、それ以降のセレクトボックスをすべてリセット&再び無効化します。
こうすることで、例えば大カテゴリを飛ばして中カテゴリだけ選ばれている、といった“歯抜け”の選択を防ぎ、条件入力の整合性を保つことができます。
HTML
<div class="wrapper">
<div class="js-step-block">
<p class="c-title">選択肢1</p>
<div class="c-select">
<select class="js-step-select">
<option value="" selected="">指定なし</option>
<option value="選択肢A">選択肢A</option>
<option value="選択肢B">選択肢B</option>
<option value="選択肢C">選択肢C</option>
</select>
</div>
</div>
<div class="js-step-block">
<p class="c-title">選択肢2</p>
<div class="c-select">
<select class="js-step-select" disabled>
<option value="" selected="">指定なし</option>
<option value="選択肢D">選択肢D</option>
<option value="選択肢E">選択肢E</option>
<option value="選択肢F">選択肢F</option>
</select>
</div>
</div>
<div class="js-step-block">
<p class="c-title">選択肢3</p>
<div class="c-select">
<select class="js-step-select" disabled>
<option value="" selected="">指定なし</option>
<option value="選択肢G">選択肢G</option>
<option value="選択肢H">選択肢H</option>
<option value="選択肢I">選択肢I</option>
</select>
</div>
</div>
</div>
.js-step-block
セレクトボックスを包括するコンテナ要素。.js-step-block
同士はHTML上で隣接していることが、このコードの前提条件です。
.js-step-select
対象となるセレクトボックス。2つ目以降には初期状態でdisabled
を付与しておきます。
Javascript(jQuery)
$(function () {
function lockStepSelectors() {
$('.js-step-select').on('change', function () {
const $this = $(this);
const $currentBlock = $this.closest('.js-step-block');
// 自分以降の .js-step-select を取得
const $nextSelects = $currentBlock.nextAll('.js-step-block').find('.js-step-select');
if ($this.val() === '') {
// 値が空の場合、自分以降をすべてロック&リセット
$nextSelects.prop('disabled', true).val('');
} else {
// 値が空でない場合、次の1つをアンロック
const $nextBlock = $currentBlock.next('.js-step-block');
if ($nextBlock.length > 0) {
$nextBlock.find('.js-step-select').prop('disabled', false);
}
}
});
}
lockStepSelectors();
});
セレクトボックスの値が変更されたとき、自分の親要素(.js-step-block
)以降のブロックを対象に処理を行います。
値が入力されていれば、次の1つのセレクトボックスのdisabled
を解除。逆に値が空であれば、自分以降のすべてをリセットしdisabled
に戻します。
inputやtextareaにも応用可能
フォームのデザインや構造によっては、.js-step-block
のような包括要素は不要です。その場合、直接「.js-step-select
」をトリガーにして、隣接配置するだけでも問題ありません。
また、今回はセレクトボックスの使用を前提としていますが、実際のフォーム要件によっては、input
やtextarea
など他の入力フォームにも応用可能です。
「入力を順番に選ばせたい」設計が必要な際、参考にしてください。