WEB業界で働く人や興味がある人に役立つ情報サイト“qam(カム)”

  • 中
  • 大

アバター画像

2026/10/08

【JavaScript】フォームの入力欄から離れたときにバルーン形式のエラーを表示する方法

投稿者: K.K.
カテゴリー: プログラム >JavaScript

お問い合わせフォームなどで、必須項目が入力されていない場合にエラーメッセージを表示したいことがあるかと思います。
一般的なフォームでは送信ボタンを押した際にまとめてエラーを表示することが多いですが、入力欄からフォーカスが外れたタイミングでエラーを表示することで、ユーザーが入力漏れに気づきやすくなります。

今回はJavaScriptの「blur」イベントを使用して、入力欄からフォーカスが外れた際に、バルーン形式のエラーメッセージを表示する方法をご紹介します。

実装イメージ

今回実装するフォームでは、以下のような動作を行います。

  • 入力欄をクリックしただけではエラーを表示しない
  • 未入力のまま別の項目に移動するとエラーを表示する
  • 入力内容を修正するとエラーを自動的に解除する
  • メールアドレスの形式が正しくない場合もエラーを表示する
  • 送信ボタンを押した際にはすべての必須項目をチェックする

エラーメッセージは入力欄の下にバルーン形式で表示し、エラーが発生している入力欄の枠線も赤色に変更します。
以下が実装サンプルです。

See the Pen
フォームの入力欄から離れたときにバルーン形式のエラーを表示する方法
by qam (@qam)
on CodePen.

HTML

まずは、フォームのHTMLを用意します。
今回は「お名前」「メールアドレス」「お問い合わせ内容」の3項目を作成します。

<form id="contact-form" novalidate>
  <div class="form-group">
    <label for="username">
      お名前 <span class="required">必須</span>
    </label>
    <input type="text" id="username" name="username"
           required aria-describedby="username-error">
    <span class="error-balloon" id="username-error"
          role="alert"></span>
  </div>

  <div class="form-group">
    <label for="email">
      メールアドレス <span class="required">必須</span>
    </label>
    <input type="email" id="email" name="email"
           required aria-describedby="email-error">
    <span class="error-balloon" id="email-error"
          role="alert"></span>
  </div>

  <div class="form-group">
    <label for="message">
      お問い合わせ内容 <span class="required">必須</span>
    </label>
    <textarea id="message" name="message"
              required aria-describedby="message-error"></textarea>
    <span class="error-balloon" id="message-error"
          role="alert"></span>
  </div>

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

各入力項目には「required」属性を設定し、必須項目であることを指定しています。
また、エラーメッセージを表示するための要素として「error-balloon」というクラスを付けたspanタグを配置しています。
フォームに設定している「novalidate」は、ブラウザ標準の入力チェックによるメッセージ表示を無効化するための属性です。

今回はJavaScriptで独自のエラーメッセージを表示するため、この属性を使用しています。

CSSでバルーンを作成する

続いて、エラーメッセージをバルーン形式で表示するためのCSSを記述します。

.form-group {
  position: relative;
  margin-bottom: 45px;
}

.error-balloon {
  display: none;
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  padding: 8px 12px;
  background: #d93636;
  color: #fff;
  font-size: 12px;
  border-radius: 5px;
  z-index: 2;
}

.error-balloon::before {
  content: "";
  position: absolute;
  bottom: 100%;
  left: 15px;
  border: 6px solid transparent;
  border-bottom-color: #d93636;
}

.form-group.is-error input,
.form-group.is-error textarea {
  border: 2px solid #d93636;
}

.form-group.is-error .error-balloon {
  display: block;
}

通常時は「display: none;」を指定してエラーメッセージを非表示にしています。
JavaScriptによって親要素に「is-error」クラスが追加されると、エラーメッセージが表示される仕組みです。

また、疑似要素「::before」を使用することで、バルーンの上部に三角形を作成しています。

JavaScriptで入力チェックを実装する

続いて、JavaScriptで入力内容をチェックする処理を実装します。

const form = document.getElementById('contact-form');
const fields = form.querySelectorAll('[required]');

function validateField(field) {
  const group = field.closest('.form-group');
  const balloon = group.querySelector('.error-balloon');
  const value = field.value.trim();
  let errorMessage = '';

  if (value === '') {
    errorMessage = '必須項目です。入力してください。';
  } else if (
    field.type === 'email' &&
    !field.validity.valid
  ) {
    errorMessage = 'メールアドレスの形式を確認してください。';
  }

  balloon.textContent = errorMessage;
  group.classList.toggle('is-error', errorMessage !== '');
  field.setAttribute(
    'aria-invalid',
    errorMessage !== '' ? 'true' : 'false'
  );

  return errorMessage === '';
}

fields.forEach(field => {
  field.addEventListener('blur', () => {
    field.dataset.touched = 'true';
    validateField(field);
  });

  field.addEventListener('input', () => {
    if (field.dataset.touched === 'true') {
      validateField(field);
    }
  });
});

form.addEventListener('submit', event => {
  event.preventDefault();

  let firstInvalidField = null;

  fields.forEach(field => {
    field.dataset.touched = 'true';

    if (!validateField(field) && !firstInvalidField) {
      firstInvalidField = field;
    }
  });

  if (firstInvalidField) {
    firstInvalidField.focus();
    return;
  }

  alert('入力チェックが完了しました。');
});

必須項目を取得する

まずは、フォーム内の必須項目を取得します。

const form = document.getElementById('contact-form');
const fields = form.querySelectorAll('[required]');

「querySelectorAll(‘[required]’)」を使用することで、required属性が設定されている入力項目をまとめて取得できます。
これにより、項目ごとに個別の処理を記述する必要がなくなります。

入力内容をチェックする

次に、入力内容をチェックする関数を作成します。

function validateField(field) {
  const group = field.closest('.form-group');
  const balloon = group.querySelector('.error-balloon');
  const value = field.value.trim();
  let errorMessage = '';

  if (value === '') {
    errorMessage = '必須項目です。入力してください。';
  } else if (
    field.type === 'email' &&
    !field.validity.valid
  ) {
    errorMessage = 'メールアドレスの形式を確認してください。';
  }

  balloon.textContent = errorMessage;
  group.classList.toggle('is-error', errorMessage !== '');
  field.setAttribute(
    'aria-invalid',
    errorMessage !== '' ? 'true' : 'false'
  );

  return errorMessage === '';
}

「trim()」を使用することで、空白のみが入力されている場合も未入力として判定しています。
また、メールアドレスの入力欄については「validity.valid」を使用して、ブラウザの入力形式チェック結果を確認しています。
エラーが存在する場合は「is-error」クラスを追加し、エラーメッセージを表示します。

フォーカスが外れた際にチェックする

今回のポイントとなるのが「blur」イベントです。

fields.forEach(field => {
  field.addEventListener('blur', () => {
    field.dataset.touched = 'true';
    validateField(field);
  });

  field.addEventListener('input', () => {
    if (field.dataset.touched === 'true') {
      validateField(field);
    }
  });
});

「blur」は入力欄からフォーカスが外れたタイミングで発生するイベントです。
このイベントを使用することで、ユーザーが入力欄を操作して別の項目へ移動した際に、入力内容をチェックできます。

また、「input」イベントを組み合わせることで、一度チェックした項目については入力内容が変更されるたびに再チェックを行います。
そのため、エラーが表示された後に正しい内容を入力すると、エラーメッセージが自動的に消えるようになります。

送信時にも入力内容をチェックする

入力欄を一度も操作せずに送信ボタンを押した場合にも対応するため、送信時にはすべての必須項目をチェックします。

form.addEventListener('submit', event => {
  event.preventDefault();

  let firstInvalidField = null;

  fields.forEach(field => {
    field.dataset.touched = 'true';

    if (!validateField(field) && !firstInvalidField) {
      firstInvalidField = field;
    }
  });

  if (firstInvalidField) {
    firstInvalidField.focus();
    return;
  }

  alert('入力チェックが完了しました。');
});

入力内容に問題がある場合は、最初にエラーが発生した入力欄へフォーカスを移動します。
なお、今回のサンプルでは「preventDefault()」によってフォームの送信を停止しています。
実際のフォームに組み込む場合は、入力チェック完了後に既存の送信処理を実行するよう調整してください。

実装時の注意点

今回の方法は、JavaScriptを使用して入力中のエラーを分かりやすく表示するためのものです。
実際のフォームに組み込む際には、以下の点に注意してください。

  • エラーメッセージが他の入力項目と重ならないように余白を確保する
  • スマートフォンでもメッセージが画面からはみ出さないようにする
  • 入力欄の枠線だけでなく、テキストでもエラー内容を伝える
  • JavaScriptによるチェックだけでなく、サーバー側でも入力内容を検証する

また、すべての項目で入力途中からエラーを表示すると、ユーザーにとって煩わしく感じられる場合があります。
今回のように、一度操作した項目だけをチェックすることで、必要なタイミングでエラーを伝えられます。

まとめ

今回は、JavaScriptを使用して入力欄からフォーカスが外れた際に、バルーン形式のエラーメッセージを表示する方法をご紹介しました。
「blur」イベントと「input」イベントを組み合わせることで、入力漏れの検出からエラーの解除までを自動的に行えます。

また、required属性が設定された項目をまとめて取得することで、複数の入力項目にも同じ処理を適用できます。
お問い合わせフォームなどで、入力時の分かりやすさを改善したい場合に活用してみてください。

コーディング業務のご依頼、ご相談の詳細についてはこちらから

最後までお読みいただき、ありがとうございました。

よろしければシェアしていただければ幸いです。

  • このエントリーをはてなブックマークに追加

関連記事

よろしければこちらの記事もお読みください。

WEB業界ならqam!qam(カム)はWEB業界で働く人や興味がある人に役立つ情報サイトです。
マーケティングやデザイン、マークアップ(コーディング)、プログラム、トレンドなどの情報をqamライター陣が執筆。噛めば噛むほど(読めば読むほど)制作・開発や運営・運用、業界知識やノウハウを学ぶことができます。

トップへ