HOME / BLOG
BLOG

JavaScriptでフォーム入力をリアルタイムに検証する方法【Constraint Validation API】

デフォルト画像

JavaScriptでフォームバリデーションを作るとき、すべてを自前で判定するとコードが増えます。まずはHTML標準の requiredtype="email"minlength を使い、その上で Constraint Validation API を組み合わせるのが扱いやすいです。

この記事では、setCustomValidity()checkValidity()reportValidity() を使って、リアルタイムにエラー文を出すフォームを作ります。

HTML

<form class="contact-form" novalidate>
  <label>
    メールアドレス
    <input id="email" type="email" required autocomplete="email">
    <span class="error" id="email-error" aria-live="polite"></span>
  </label>

  <label>
    お問い合わせ内容
    <textarea id="message" required minlength="10"></textarea>
    <span class="error" id="message-error" aria-live="polite"></span>
  </label>

  <button type="submit">送信する</button>
</form>

JavaScript

const form = document.querySelector(".contact-form");
const email = document.querySelector("#email");
const message = document.querySelector("#message");
const emailError = document.querySelector("#email-error");
const messageError = document.querySelector("#message-error");

function updateEmailError() {
  email.setCustomValidity("");

  if (email.validity.valueMissing) {
    email.setCustomValidity("メールアドレスを入力してください。");
  } else if (email.validity.typeMismatch) {
    email.setCustomValidity("メールアドレスの形式で入力してください。");
  }

  emailError.textContent = email.validationMessage;
}

function updateMessageError() {
  message.setCustomValidity("");

  if (message.validity.valueMissing) {
    message.setCustomValidity("お問い合わせ内容を入力してください。");
  } else if (message.validity.tooShort) {
    message.setCustomValidity("10文字以上で入力してください。");
  }

  messageError.textContent = message.validationMessage;
}

email.addEventListener("input", updateEmailError);
message.addEventListener("input", updateMessageError);

form.addEventListener("submit", (event) => {
  updateEmailError();
  updateMessageError();

  if (!form.checkValidity()) {
    event.preventDefault();
    form.reportValidity();
    return;
  }
});

CSS

.contact-form {
  display: grid;
  gap: 18px;
  max-width: 560px;
}

.contact-form label {
  display: grid;
  gap: 8px;
  font-weight: 700;
}

.contact-form input,
.contact-form textarea {
  width: 100%;
  padding: 12px 14px;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  font: inherit;
}

.contact-form input:invalid,
.contact-form textarea:invalid {
  border-color: #d12f2f;
}

.error {
  min-height: 1.5em;
  color: #d12f2f;
  font-size: .9rem;
}

使っているAPI

API役割
validity入力欄がどのルールに違反しているかを確認する
setCustomValidity()ブラウザ標準の検証結果に独自メッセージを設定する
checkValidity()フォーム全体が送信できる状態かを真偽値で確認する
reportValidity()ユーザーにブラウザ標準のエラーUIを表示する

注意点

  • フロントエンドの検証だけで完結させず、サーバー側でも必ず検証する
  • novalidate を付ける場合は、自前で送信時のチェックを呼ぶ
  • エラー文を表示する要素には aria-live を付けると状態変化が伝わりやすい
  • 日本語のエラー文は短く、次に何をすればよいか分かる形にする

あわせて読みたい

参考資料