JavaScript | DOM 操作:フォーム操作 – checked の操作

JavaScript JavaScript
スポンサーリンク

checked とは何か

checked は、checkbox と radio の「選択状態」を表す真偽値プロパティです。true なら選ばれている、false なら選ばれていない状態を意味します。ここが重要です:checked は“状態”で、送信時に渡す“文字列”は value。未チェックの checkbox は FormData にキー自体が入らないため、存在判定を使うのが正確です。


checkbox の読み取り・書き換え(状態と送信値の切り分け)

現在の選択状態を読む・変更する

<input id="agree" type="checkbox" value="yes">
<script>
  console.log(agree.checked); // true/false
  agree.checked = true;       // 選択状態にする
  agree.checked = false;      // 選択解除
</script>
HTML

ここが重要です:checked はブール値で直接読む・書く。見た目のトグルに対応します。

送信相当の値を理解する(FormData)

<form id="f">
  <input name="agree" type="checkbox" value="yes">
</form>
<script>
  const fd1 = new FormData(f); console.log(fd1.has("agree")); // false(未チェック)
  f.elements.agree.checked = true;
  const fd2 = new FormData(f); console.log(fd2.get("agree")); // "yes"
</script>
HTML

ここが重要です:未チェックは“キーがない”。checked を見るか、FormData.has(“agree”) で有無判定をすると確実です。value は“送る文字列”であり、状態そのものではありません。

indeterminate(半チェック)で「一時表示だけ半透明」

<input id="all" type="checkbox">
<script>
  all.indeterminate = true; // 半チェックの視覚状態(送信・ロジック上は未選択)
HTML

ここが重要です:indeterminate は“見た目の中間状態”を出すだけ。checked ではないため、送信も選択処理もされません。マスター選択の視覚に便利です。


radio の読み取り・書き換え(グループで扱うのが正解)

選ばれている一つを読む

<form id="f">
  <label><input type="radio" name="color" value="red">赤</label>
  <label><input type="radio" name="color" value="blue">青</label>
</form>
<script>
  const group = f.elements["color"]; // RadioNodeList
  console.log(group.value);          // 選択中の value(未選択なら空文字)
</script>
HTML

ここが重要です:同じ name のラジオは“集合”として扱い、RadioNodeList.value で現在の選択値が取れます。

プログラムで選択する

<script>
  // value 指定で選択
  [...group].forEach(r => r.checked = (r.value === "blue"));

  // あるいは個別参照してチェック
  const red = [...group].find(r => r.value === "red");
  red.checked = true;
</script>
HTML

ここが重要です:ラジオは一つだけが選ばれるため、checked を true にした瞬間、他は自動で false になります。


イベントと UI 同期(input / change と明示発火)

ユーザー操作に反応して処理する

<input id="agree" type="checkbox">
<script>
  agree.addEventListener("input",  () => console.log("途中変化:", agree.checked));
  agree.addEventListener("change", () => console.log("確定:", agree.checked));
</script>
HTML

ここが重要です:input は“即時”、change は“確定後”に発火。ライブ反応なら input、検証や送信前の最終チェックは change が向いています。

プログラム変更でイベントを発火させる

<script>
  agree.checked = true; // これだけでは change が発火しないことが多い
  agree.dispatchEvent(new Event("change", { bubbles: true }));
</script>
HTML

ここが重要です:コードで状態を変えた後にロジックを走らせたい場合、イベントを明示的に dispatch します。


実践例(すべて選択・一部選択と indeterminate・相互排他)

チェックボックスの「すべて選択」を正しく実装

<input id="all" type="checkbox"> 全て
<div>
  <label><input class="item" type="checkbox" value="A">A</label>
  <label><input class="item" type="checkbox" value="B">B</label>
  <label><input class="item" type="checkbox" value="C">C</label>
</div>
<script>
  const items = [...document.querySelectorAll(".item")];

  function syncMaster() {
    const checkedCount = items.filter(i => i.checked).length;
    all.checked = checkedCount === items.length;
    all.indeterminate = checkedCount > 0 && checkedCount < items.length;
  }
  all.addEventListener("change", () => {
    items.forEach(i => i.checked = all.checked);
    syncMaster();
  });
  items.forEach(i => i.addEventListener("change", syncMaster));
  syncMaster();
</script>
HTML

ここが重要です:マスター側は“全選択なら checked、部分選択なら indeterminate”。視覚と状態を分けて管理すると、直感的でバグが減ります。

相互排他の「トグル一択」を checkbox で再現

<label><input class="solo" type="checkbox" value="A">A</label>
<label><input class="solo" type="checkbox" value="B">B</label>
<script>
  const boxes = [...document.querySelectorAll(".solo")];
  boxes.forEach(b => b.addEventListener("change", () => {
    if (b.checked) boxes.forEach(o => { if (o !== b) o.checked = false; });
  }));
</script>
HTML

ここが重要です:見た目はチェックボックスでも、同時に一つだけ選べる挙動を作れます。実態はラジオに近い仕様ですが、柔らかい UI が必要なときに使えます。


フォーム送信と検証(必須・エラー表示・存在判定)

必須チェックとエラーメッセージ

<form id="f">
  <label><input id="agree" name="agree" type="checkbox">規約に同意</label>
  <button>送信</button>
</form>
<script>
  f.addEventListener("submit", (e) => {
    if (!agree.checked) {
      e.preventDefault();
      alert("送信には同意が必要です");
    }
  });
</script>
HTML

ここが重要です:必須条件は checked を見るのがシンプル。送信相当の確認には FormData.has(“agree”) を使っても正確です(未チェックはキーなし)。

FormData で存在判定(サーバーと同じ見え方)

<script>
  const fd = new FormData(f);
  const agreed = fd.has("agree"); // true/false
</script>
HTML

ここが重要です:checked を見るのと等価ですが、サーバーと同じ“送信パケットの視点”で判定できるため、仕様の整合が保ちやすいです。


よくある落とし穴と回避策

value と checked の混同

value は送る文字列、checked は状態。未チェック時は value では判定できません。存在判定(checked か FormData.has)を使う。

multiple な checkbox を単一値として扱ってしまう

複数選択は配列で扱います。FormData.getAll(“name”) で全選択の値を取得するか、DOM を列挙して checked のものを集めます。

indeterminate を“選択状態”だと思い込む

indeterminate は視覚だけ。送信やロジック上は未選択扱い。表示とロジックを分離して考える。

プログラム変更でイベントが発火しない

コードで checked を変えた後に処理が必要なら、dispatchEvent で change を明示発火する。

ラジオを単一 input として参照して空振り

同じ name の集合で RadioNodeList を扱い、group.value で選択値を取得する。個別操作は checked を true にするだけで他が外れる。


まとめ

checked は checkbox と radio の「選択状態」を表す中核プロパティで、値(value)とは役割が異なります。checkbox は未チェックだと送信に含まれないため、存在判定が要点。radio は name グループで扱い、RadioNodeList.value が最短ルートです。UI ではマスター選択に indeterminate を活用し、イベントは input/change を目的に応じて使い分け、プログラム変更時は明示発火で同期する。これらを押さえれば、初心者でも読みやすく壊れにくい「checked の操作」を自信をもって実装できます。

タイトルとURLをコピーしました