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

JavaScript JavaScript
スポンサーリンク

input の value とは何か

input 要素の value は「現在の入力値」を表す文字列です。type に関わらず、基本は文字列として読み書きします。ここが重要です:type=”number” でも value は文字列。計算したいときは Number(…) や parseFloat(…) で明示的に数値へ変換します。チェックボックスやラジオは“選択状態”(checked)と“文字列の value”が別物なので、使い分けが鍵です。


値の読み書きの基本(現在値・初期値・イベント)

いまの値を読む/書く

<input id="age" type="number" placeholder="年齢">
<script>
  console.log(age.value);        // 例: "23"(文字列)
  age.value = "24";              // プログラムで書き換え
</script>
HTML

ここが重要です:placeholder は表示上のヒントであり、value には入りません。プログラムから書き換えた値は、次の submit や FormData 取得に反映されます。

初期値(defaultValue)と現在値の違い

<input id="name" value="太郎">
<script>
  console.log(name.defaultValue); // "太郎"(HTMLで書かれた初期値)
  console.log(name.value);        // ユーザー操作やJSで変わる“現在値”
</script>
HTML

ここが重要です:defaultValue は初期表示を再現したいときに参照・復元に使えます。リセット(form.reset())は defaultValue に戻します。

いつ反応するか(input と change)

<input id="email" type="email">
<script>
  email.addEventListener("input",  () => console.log("入力途中:", email.value));
  email.addEventListener("change", () => console.log("確定後:", email.value));
</script>
HTML

ここが重要です:input は“タイピング中”に逐次、change は“確定後”(フォーカスが外れた等)に発火。ライブ検証は input、最終チェックや送信前確認は change が向いています。


type ごとの value の扱い(文字列が原則、例外の理解)

テキスト・数値・パスワードなど(文字列で扱う)

<input id="price" type="number" min="0" step="0.01">
<script>
  const n = parseFloat(price.value || "0"); // 空文字対策
  if (Number.isNaN(n)) { /* エラー扱い */ }
</script>
HTML

ここが重要です:空文字は Number(…) で NaN。未入力の扱いを必ず決めておき、デフォルト値や検証メッセージを用意します。HTML の min/max/step はブラウザ検証の補助ですが、ロジック側でも検証を行うと安心です。

チェックボックスとラジオ(checked と value の役割)

<input id="agree" type="checkbox" value="yes">
<label><input name="color" type="radio" value="red">赤</label>
<label><input name="color" type="radio" value="blue">青</label>
<script>
  console.log(agree.checked);     // true/false(選択状態)
  console.log(agree.value);       // "yes"(選択時に送る文字列)
  // ラジオは“グループの選択値”を見る
  const group = document.querySelectorAll('input[name="color"]');
  const selected = [...group].find(r => r.checked)?.value || "";
</script>
HTML

ここが重要です:状態は checked、送る文字列は value。checkbox が未チェックなら FormData にキー自体が入りません(既定の value は “on”)。ラジオは“同じ name の中で一つ”だけが checked になります。

ファイル入力(value は使わない)

<input id="avatar" type="file" accept="image/*">
<script>
  const file = avatar.files[0]; // File オブジェクトで扱う
  if (file) console.log(file.name, file.size);
</script>
HTML

ここが重要です:file の value はパス風文字列ですが使いません。実データは files の File オブジェクトで扱い、アップロードは FormData に append します。

日付・時刻のフォーマット

<input id="d" type="date">
<input id="t" type="time" step="1">
<script>
  console.log(d.value); // "2025-12-14" のようなISO風文字列
  console.log(t.value); // "13:45:07" など、step に応じたフォーマット
</script>
HTML

ここが重要です:date/time は標準化された文字列で返ります。サーバー送信や比較がしやすい一方、ロケール表示と値フォーマットは別なので混同しない。


値の整形と入力体験(トリミング・正規化・IME配慮)

前後の空白を消して扱う(送信前整形)

<input id="username">
<script>
  function normalized(v) {
    return v.trim(); // 必要なら全角半角の正規化も
  }
  const clean = normalized(username.value);
</script>
HTML

ここが重要です:送信・検索の前に trim するだけで“意図しない空白”による不一致を減らせます。必要なら全角スペースや濁点の正規化も検討。

フォーマット表示と値の分離

<input id="money" inputmode="numeric">
<script>
  money.addEventListener("input", () => {
    const raw = money.value.replace(/[^\d.]/g, "");
    money.value = raw; // 値は常に“生”を維持
    // 見た目のフォーマットは別の表示要素で
  });
</script>
HTML

ここが重要です:値を“生”で保持し、フォーマット(カンマ区切り等)は別要素で表示すると、カーソル飛びや IME との競合が減ります。どうしても中でフォーマットする場合は selectionStart/End を保持・復元してカーソルを守ります。

IME 合成中の扱い(composition への配慮)

<input id="jp">
<script>
  let composing = false;
  jp.addEventListener("compositionstart", () => composing = true);
  jp.addEventListener("compositionend",   () => composing = false);
  jp.addEventListener("input", () => {
    if (composing) return; // 合成中は検証や整形を遅らせる
    // 検証・整形処理
  });
</script>
HTML

ここが重要です:日本語入力中(composition)の途中で強い整形やエラー表示をかけると体験が悪化します。確定後に処理する設計が安全です。


値の取得・送信の定番パターン(FormData と検証)

FormData で“送信相当”の値を一括取得

<form id="f">
  <input name="email" value="a@example.com">
  <input name="agree" type="checkbox"> <!-- 未チェックならキーが無い -->
</form>
<script>
  const data = new FormData(f);
  console.log(data.get("email")); // "a@example.com"
  console.log(data.has("agree")); // true/false(チェックの有無)
  console.log([...data.entries()]); // すべての [name, value]
</script>
HTML

ここが重要です:FormData は実際の送信内容を再現します。checkbox は未チェックだと“キーなし”。必須判定は has()/get() で行うと正確です。

ブラウザ組み込みの検証と組み合わせる

<input id="mail" type="email" required>
<script>
  mail.addEventListener("blur", () => {
    if (!mail.checkValidity()) {
      mail.classList.add("error");
    } else {
      mail.classList.remove("error");
    }
  });
</script>
HTML

ここが重要です:HTML の required/type 属性で基本検証は賄えます。ロジック側は“確定後(blur)に優しく検証”し、入力中はヒント表示に留めると体験が良くなります。


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

number の value を数値だと思い込む

value は文字列。ここが重要です:計算は必ず Number/parseFloat へ明示変換。空文字→NaN の扱いを決める。

checkbox の value を“状態”と誤解

状態は checked、文字列は value。未チェックは FormData に値が載らない。ここが重要です:has()/get() で存在判定する。

ラジオの選択値を単一 input から拾おうとして空振り

ラジオは“同じ name の集合”で扱う。ここが重要です:querySelectorAll でグループ化して checked の value を取るか、form.elements[“name”].value を使う。

入力途中に強制整形してカーソルが暴れる

整形は合成完了後(compositionend)や blur 時に行う。ここが重要です:どうしてもライブ整形するなら selectionStart/End を保存してから復元。

placeholder を値だと思って送信する

placeholder はヒントであり value ではない。ここが重要です:未入力の扱い(必須・デフォルト値)を設計で明確に。


まとめ

input の value は「現在の入力値」を表す文字列で、type に関係なく文字列として扱うのが原則です。計算時は明示的に数値化し、checkbox/radio は checked(状態)と value(送る文字列)を使い分けます。値の取得は value/form.elements/FormData を目的別に使い分け、検証はブラウザ組み込みと blur/input のタイミングで優しく行う。IME 合成やカーソル位置の配慮、trim/正規化で体験を整えると、初心者でも“壊れにくくて読みやすい”フォーム値処理が書けます。

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