MENU

【JavaScript】フォーム(formタグ)の操作を解説|Webの基礎

JavaScriptでのフォーム(formタグ)操作解説|Webの基礎
目次

はじめに

前回の記事では、<img>タグ(イメージ)をJavaScriptで操作する方法を解説しました。

今回は、お問い合わせフォームや検索窓など、Webサイトに欠かせないフォーム(<form>タグ)をJavaScriptで操作する方法を解説します。フォーム要素の取得、値の取得・設定、送信(submit)時のバリデーション、FormDataによる値の一括取得まで、実務でよく使う内容を中心に紹介します。

<form> タグの基本をおさらい

まずはHTMLの<form>タグの基本をおさらいします。

<form action="/submit" method="post" name="contactForm">
    <input type="text" name="username" required>
    <input type="email" name="email">
    <select name="category">
        <option value="a">お問い合わせ</option>
        <option value="b">ご意見・ご要望</option>
    </select>
    <button type="submit">送信</button>
</form>
属性内容
action送信先のURL
method送信方法(getまたはpost
nameフォームの名前(document.formsで参照する際に使用)
novalidateHTML標準のバリデーションを無効化する

<form>内に配置する<input><select><textarea>などの部品タグについては、【HTML】フォーム部品<input>について【HTML】フォーム部品タグとは?で詳しく解説しています。

フォーム要素を取得する

フォーム自体はdocument.forms、フォーム内の各部品はform.elementsで取得できます。

const form = document.forms["contactForm"]; // name属性で取得
// const form = document.querySelector("form"); でも可

console.log(form.elements["username"]); // name属性で個別の部品を取得
console.log(form.elements.length); // フォーム内の部品数

document.formsname属性をキーにしたコレクションで、form.elementsも同様に各部品のname属性で参照できます。document.querySelector【JavaScript】documentオブジェクトを解説)でCSSセレクタを使って取得することもできますが、フォーム部品に関してはname属性で参照する方がシンプルに書けます。

document.formsとform.elementsで各部品にアクセスするイメージ図

値を取得・設定する(value・checked・selected)

部品の種類によって、値の取得・設定に使うプロパティが異なります。

const form = document.forms["contactForm"];

// テキスト・メールなど
form.elements["username"].value = "山田太郎";
console.log(form.elements["username"].value);

// チェックボックス・ラジオボタン
form.elements["agree"].checked = true;
console.log(form.elements["agree"].checked); // true / false

// セレクトボックス
form.elements["category"].value = "b"; // option要素のvalueを指定
console.log(form.elements["category"].selectedIndex); // 選択中のインデックス

チェックボックス・ラジオボタンはvalueではなくchecked(真偽値)で選択状態を扱う点に注意してください。同じnameを持つラジオボタンが複数ある場合は、form.elements["group名"]RadioNodeListとして取得され、.valueにはチェックされている項目の値が入ります。

チェックボックスのcheckedとHTML属性のcheckedは別物です。HTML側のchecked属性は「初期状態」を表すだけで、JavaScriptで操作するのは常にプロパティのcheckedです。

submitイベントを制御する(送信前の処理)

フォームが送信される瞬間にはsubmitイベントが発生します。clickイベントをボタンに仕込むより、formsubmitイベントを仕込む方が、Enterキーによる送信も含めて確実に処理できます。

const form = document.forms["contactForm"];

form.addEventListener("submit", (event) => {
    event.preventDefault(); // 標準の送信動作をキャンセル

    const ok = confirm("この内容で送信してよろしいですか?");

    if (ok) {
        form.submit(); // 手動で送信(addEventListener("submit")は発火しない)
    }
});

【JavaScript】ダイアログボックスを解説で紹介したconfirm()と組み合わせることで、送信前に内容確認を挟めます。event.preventDefault()でいったん標準の送信をキャンセルし、確認が取れた場合のみform.submit()で改めて送信している点がポイントです。

form.submit()で送信すると、addEventListener(“submit”)で登録したイベントは再発火しません。ボタンのclickイベントを直接呼び出すJavaScript側からの送信は、ブラウザの標準動作とは扱いが異なるためです。

入力チェック(バリデーション)を行う

フォームの入力チェックは、HTML標準の機能とJavaScriptによるメソッドを組み合わせて行います。

<input type="text" name="username" required minlength="2">
<input type="email" name="email" required>

requiredminlengthpatternなどの属性を指定するだけで、ブラウザが標準のエラーメッセージとともに送信をブロックしてくれます。これに加えて、JavaScriptから明示的にチェックしたい場合はcheckValidity()reportValidity()を使います。

const form = document.forms["contactForm"];

form.addEventListener("submit", (event) => {
    if (!form.checkValidity()) {
        event.preventDefault(); // 不正な入力があれば送信をキャンセル
        form.reportValidity(); // ブラウザ標準のエラー表示を出す
        return;
    }

    // ここに独自のチェックを追加できる
    const email = form.elements["email"].value;

    if (!email.includes("@")) {
        event.preventDefault();
        alert("正しいメールアドレスを入力してください");
    }
});

checkValidity()はフォーム全体(または個別の部品)がrequiredなどの条件を満たしているかを判定し、結果をtrue/falseで返します。reportValidity()は判定に加えて、ブラウザ標準のエラー吹き出しを実際に表示させるメソッドです。属性だけでは表現できない独自ルール(文字種のチェックなど)は、この後にJavaScriptで追加判定します。

FormDataでまとめて値を取得する

フォーム内のすべての値をまとめて扱いたい場合は、FormDataオブジェクトが便利です。部品を1つずつelementsで取得する必要がありません。

const form = document.forms["contactForm"];
const formData = new FormData(form);

console.log(formData.get("username")); // 個別に取得
console.log(formData.get("email"));

for (const [key, value] of formData) {
    console.log(key, value); // すべてのキーと値を列挙
}

new FormData(form)は、フォーム内の各部品のname属性をキーとして値をまとめて保持するオブジェクトです。get()で個別に取り出せるほか、for...ofで全項目をまとめて取り出すこともできます。サーバーへ送信する際(fetchのリクエストボディなど)にもそのまま利用できる形式です。

FormDataはチェックが外れているチェックボックスの値を含みません。未チェックの項目も扱いたい場合は、elementsから個別にcheckedを確認する必要があります。

実務サンプル(入力チェック+送信前確認)

入力チェックを行い、問題がなければ送信前に内容を確認ダイアログで表示するサンプルです。

HTML

<form id="contactForm" action="/submit" method="post">
    <input type="text" name="username" placeholder="お名前" required>
    <input type="email" name="email" placeholder="メールアドレス" required>
    <textarea name="message" placeholder="お問い合わせ内容" required></textarea>
    <button type="submit">送信</button>
</form>

JavaScript(main.js)

document.addEventListener("DOMContentLoaded", () => {
    const form = document.getElementById("contactForm");

    form.addEventListener("submit", (event) => {
        event.preventDefault(); // まず標準の送信をキャンセル

        if (!form.checkValidity()) {
            form.reportValidity(); // 未入力・不正な値があればブラウザ標準の警告を表示
            return;
        }

        const formData = new FormData(form);
        const summary = [...formData.entries()]
            .map(([key, value]) => `${key}: ${value}`)
            .join("\n");

        const ok = confirm(`以下の内容で送信します。\n\n${summary}`);

        if (ok) {
            form.submit(); // 確認後に手動で送信
        }
    });
});

submitイベント発生時にまずpreventDefault()で標準送信をキャンセルし、checkValidity()で必須項目のチェックを行います。問題がなければFormDataで全項目を集約し、内容をconfirm()で表示したうえで、OKが押された場合のみform.submit()で実際に送信しています。

未入力のまま送信すると、以下のように各項目にエラー表示が出て送信がブロックされます。

未入力のまま送信してバリデーションエラーが表示された画面

入力チェックを通過すると、confirm()で送信内容の確認ダイアログが表示されます。

FormDataでまとめた内容をconfirm()の確認ダイアログで表示している画面

よくある質問・エラー対処

Q. preventDefault()を呼ばないとどうなる?

→ フォームは即座にactionで指定したURLへ送信され、ページが遷移してしまいます。送信前にJavaScriptで確認やバリデーションを挟みたい場合は、必ずsubmitイベント内でpreventDefault()を呼んでから処理を進める必要があります。

Q. checkValidity()reportValidity()はどちらを使えばいい?

→ 判定結果(true/false)だけを使ってJavaScript側で独自にエラー表示を出したいならcheckValidity()、ブラウザ標準のエラー吹き出しをそのまま表示させたいならreportValidity()を使います。両方を組み合わせて使うことも多いです。

Q. FormData.get("項目名")nullになる

→ 指定したname属性がフォーム内に存在しない、またはスペルミスをしている場合がほとんどです。console.log([...formData.keys()])で実際に取得できているキー一覧を確認してみてください。

おわりに(まとめ)

まとめ

JavaScriptでフォーム(formタグ)を操作すると、入力チェックや送信前の確認など、使い勝手と安全性を高める工夫ができます。

  • ✅ document.formsとform.elementsで、フォームと部品をname属性から取得できる
  • ✅ テキストはvalue、チェックボックス・ラジオボタンはcheckedで値を扱う
  • ✅ submitイベント+preventDefault()で送信前に独自の処理を挟める
  • ✅ checkValidity()・reportValidity()でHTML標準のバリデーションと連携できる
  • ✅ FormDataを使えば、フォーム内の値を一括で取得・列挙できる

まずはsubmitイベントでのpreventDefault()と入力チェックから試してみましょう。

次回は、文字列の操作について解説予定です。

この記事が、少しでも誰かのお役に立てれば幸いです。

関連記事

当サイトの記事で使用したVBAなどのサンプルをDLできます

この記事のサンプルはありません!

ダウンロードページへは下のカードをクリックすればジャンプできます。
よろしければご利用ください!


【CSS】テキスト関連プロパティについて基本解説|Webの基礎


よかったらシェアしてね!
  • URLをコピーしました!
目次