ミギムキ

[JavaScript] チェックボックス・ラジオボタンの初期値をGETパラメーターで自動設定したい

チェックボックス・ラジオボタンの初期値を設定したい

動作イメージ

サンプルコード

html

<form action="" method="get" class="set_initial"> <dl> <dt>チェックボックス</dt> <dd> <label><input type="checkbox" name="cb[]" value="cb_01">チェック1</label> <label><input type="checkbox" name="cb[]" value="cb_02">チェック2</label> <label><input type="checkbox" name="cb[]" value="cb_03">チェック3</label> </dd> <dt>ラジオボタン</dt> <dd> <label><input type="radio" name="rd" value="rd_01">ラジオ1</label> <label><input type="radio" name="rd" value="rd_02">ラジオ2</label> <label><input type="radio" name="rd" value="rd_03">ラジオ3</label> </dd> <dt>テキストボックス</dt> <dd> <input type="text" name="txt" value=""> </dd> </dl> <input type="submit" value="送信"> <input type="reset" value="リセット"> </form>

Javascript

window.addEventListener('load', function() { const forms = document.getElementsByClassName('set_initial'); // 対象となるフォームがなければ終了 if(!forms.length) { return; } // 先頭の?を除いたパラメーターを取得 const searchParams = location.search.slice(1).split('&'); for(let i = 0; i < forms.length; i++) { const inputItems = forms[i].getElementsByTagName('input'); for(let j = 0; j < inputItems.length; j++) { const inputItem = inputItems[j]; const type = inputItem.getAttribute('type'); for(let k = 0; k < searchParams.length; k++) { const params = searchParams[k].split('='); if(params[0] != null && params[1] != null) { const key = decodeURI(params[0]); const value = decodeURI(params[1]); // リセットボタン押下時のイベントを設定 if(type === 'reset') { inputItem.addEventListener('click', function() { location.href = location.href.replace(location.search, ''); }, false); } // 入力項目のnameとkeyが一致しないならスキップ if(inputItem.getAttribute('name') === key) { if(type === 'checkbox' || type === 'radio') { if(inputItem.getAttribute('value') === value) { inputItem.setAttribute('checked', 'checked'); } } else if(type === 'text' || type === 'hidden') { inputItem.setAttribute('value', value); } else { // dummy } } } } } } }, false);

サンプルコードの解説

チェックボックスにつけるname属性

<label><input type="checkbox" name="cb[]" value="cb_01">チェック1</label> <label><input type="checkbox" name="cb[]" value="cb_02">チェック2</label> <label><input type="checkbox" name="cb[]" value="cb_03">チェック3</label>
  • 複数項目にチェックが可能なチェックボックスは、値を配列で受け取る必要があります
  • name属性には[]をつけることで、パラメーターを配列として受け取ることができます

入れ子になったループの構造について

for(let i = 0; i < forms.length; i++) { 〜〜〜 for(let j = 0; j < inputItems.length; j++) { 〜〜〜 for(let k = 0; k < searchParams.length; k++) { 〜〜〜 } } }
  • Javascriptの処理は3つのループを入れ子にしています
  • 1つ目は、配列「forms」の数分回すループです。サイドバーなど他のフォームが誤動作しないよう、初期値設定するフォームには「set_initial」クラスを設定します。このクラスが設置された「form」タグの数だけループ処理します
  • 2つ目は、配列「inputItems」の数分回すループです。「form」内の「input」タグの数だけループします
  • 3つ目は、配列「searchParams」の数分回すループです。get方式で渡されたパラメーターの数だけループします。ループ中のinputタグとパラメーターを比較して、初期値設定が必要な要素かチェックします

GETパラメーターの取得と加工

https://xxx.com/?cb%5B%5D=cb_01&cb%5B%5D=cb_02&rd=rd_03&txt=
  • get方式で送信されると、URL末尾に「?」から始まるパラメーターが設定されます
  • 各パラメーターは「&」で区切られています
// 先頭の?を除いたパラメーターを取得 const searchParams = location.search.slice(1).split('&');
  • 「location.search」で「?」から始まるパラメーターが取得できます
  • パラメーターに対して「slice」関数を使って先頭「?」を削除し、更に「split」関数を使って「&」で分割したパラメーターを配列にセットします
const params = searchParams[k].split('='); const key = decodeURI(params[0]); const value = decodeURI(params[1]);
  • 個々のパラメーターは[name属性] = [value属性]といった形に「=」で分けられています
  • 再度「split」関数を使って「=」で分割し、name属性の内容を変数「key」、value属性の内容を「value」にそれぞれセットします

チェックボックス・ラジオボタンを選択状態にする

if(inputItem.getAttribute('name') === key) { if(type === 'checkbox' || type === 'radio') { if(inputItem.getAttribute('value') === value) { inputItem.setAttribute('checked', 'checked'); } } else if(type === 'text' || type === 'hidden') { inputItem.setAttribute('value', value); } else { // dummy } }
  • 各inputタグの初期値を設定する処理です
  • まずはループ中のkeyが、ループ中のinputタグに設定された「name」属性と一致するかを判定します
  • 次にinputタグの「type」属性をチェックし、チェックボックスかラジオボタンであれば、更に「value」属性の内容と、getで渡された値である変数「value」の内容が一致しているかを判定し、一致しているならinputタグの「checked」属性を有効にします
  • 選択形式ではない「text」と「hidden」については、素直に「value」属性に変数「value」の内容をセットして初期値とします

リセットボタンの処理

// リセットボタン押下時のイベントを設定 if(type === 'reset') { inputItem.addEventListener('click', function() { location.href = location.href.replace(location.search, ''); }, false); }
  • 今回紹介した初期値設定処理を行うと、従来のリセットボタンが機能しなくなってしまいます。リセットボタンを押して項目がクリアされた後に、getパラメーターで初期値が再設定されるからです
  • そこで、リセットボタンの処理を拡張し、ボタンが押されたときにgetパラメーター(アドレスの「?」以降の内容)をクリアしたURLで再読み込みするようにしています

ご質問など受け付けています

記事の中でわかりにくかったところ、もっと知りたかったこと、間違っていることなど、何でもお気軽にご連絡ください。

ご連絡は下記フォームを利用いただくか、ツイッターアカウント@flat8migi宛てでもOKです。