at backyard

Color my life with the chaos of trouble.

【備忘録】JavaScriptでRadioNodeListを配列に変換する

JavaScriptに関する個人的なメモ、備忘録。

RadioNodeList を配列に変換して処理したいときがあって、配列に変換するための方法を調べたメモです。

例えば下記のようなradioボタンを配置したフォームがあるとする。

<div>
  <form name="testTypeForm">
    <div>
      <input type="radio"
             id="test1"
             name="testType"
             value="test1"
             checked />
      <label for="test1">Test 1</label>
    </div>
    <div>
      <input type="radio"
             id="test2"
             name="testType"
             value="test2" />
      <label for="test2">Test 2</label>
    </div>
    <div>
      <input type="radio"
             id="test3"
             name="testType"
             value="test3" />
      <label for="test3">Test 3</label>
    </div>
    <div>
      <input type="radio"
             id="test4"
             name="testType"
             value="test4" />
      <label for="test4">Test 4</label>
    </div>
    <div>
      <input type="radio"
             id="test5"
             name="testType"
             value="test5" />
      <label for="test5">Test 5</label>
    </div>
  </form>
  <button onClick="checkSelectedType()">Check selected test type</button>
</div>

そしてJavaScriptはこれ。

function checkSelectedType() {
  console.log(document.testTypeForm.testType)
}

この状態でCheck selected test type のボタンを押すと、checkSelectedType関数が動くが、console.logとして吐き出されるのは配列ではなくRadioNodeListというもの。

詳細はこちら。

developer.mozilla.org

説明文を翻訳したものが下記。

要素にラジオボタンが含まれている場合、valueプロパティはチェックされたラジオボタンを表します。value プロパティを取得すると、現在チェックされているラジオボタンの値(value)が文字列として返されます。コレクションにラジオボタンが含まれていない場合や、コレクション内のどのラジオボタンもチェックされていない場合は、空の文字列が返されます。valueプロパティの設定時には、valueプロパティが新しい値と等しい最初のラジオボタンの入力要素がcheckedに設定されます。

つまり、上のJavaScriptを下記のように変更すると、ラジオボタンで選択されているvalueがログとして表示されるようになる。

function checkSelectedType() {
  console.log(document.testTypeForm.testType.value)
}

さて、このRadioNodeList、配列ではないので、例えば下記のようなコードを書くと、undefinedが返ってくる。

function checkSelectedType() {
  console.log(document.testTypeForm.testType.find) // undefined
}

配列ではないので当然なのだが、では、配列として扱いたいようなときはどうすればよいかというと、下記のようにコードを修正する。

function checkSelectedType() {
  console.log(Array.prototype.slice.call(document.testTypeForm.testType).find); // 配列に変換されるので、find関数は存在する
}

ただ、この方法は今の時代には見づらい。
ES6以降であればArray.fromが使えるので下記のように書ける。

function checkSelectedType() {
  console.log(Array.from(document.testTypeForm.testType).find);
}

例えば、下記のように書くことでRadioNodeListを配列に変換した上で、チェックが付けられている項目を取得できる。
(最初にも書いたが、RadioNodeList.valueを使えばそれで完結するので、この方法にはなんの意味もない)

function checkSelectedType() {
  const testTypeList =  Array.from(document.testTypeForm.testType);
  const checkedType = testTypeList.find(({checked}) => checked).value;
  console.log({checkedType})  // チェックを付けている項目のvalueが表示される
}

なお、ここに書いた方法は下記のstack overflowを参考にしている。

stackoverflow.com