バリデーションチェックとは?HTMLで実装してみよう【お問い合わせフォームを作ってみよう:バリデーションチェック編(HTML)】

チュートリアル

はじめに

この記事は「お問い合わせフォームを作ってみよう」チュートリアルの一部であり、このチュートリアルのバリデーションチェック編(HTML)として書かれています。

この記事では、バリデーションチェックの概要を学び、ここまで作成してきたお問い合わせフォームのHTML要素に属性を追加し、バリデーションチェックの実装を行います。

バリデーションチェックを適切に行うことで、ユーザビリティ・セキュリティの向上やサーバーの負荷軽減が期待できます。

HTMLでのバリデーションチェックの実装は比較的簡単なので、ウェブ制作初心者の方でも実装することができるでしょう。

この記事の対象者

  • ウェブ制作初心者の方
  • お問い合わせページを作りたい方
  • バリデーションチェックが分からない方

この記事で学べること

  • バリデーションチェックの概要
  • HTML で実装できる基本的なバリデーションチェック
  • バリデーションチェックを実装する際の考え方

バリデーションチェックについて

ユーザーが入力フォームに入力した値が適切かどうかを検証することを、バリデーションチェックといいます。

バリデーションチェックはユーザビリティを向上させ、入力された値の品質を維持する役割を果たします。

バリデーションチェックの実装は、セキュリティやユーザビリティ、パフォーマンスの観点からどのような仕様で行うかを考えます。 また、HTML や JavaScript で実装するフロントエンド側のバリデーションチェックはユーザビリティに影響を与え、 PHP などで実装するサーバーサイド側のバリデーションチェックはセキュリティの面で重要な役割を果たします。

よって、バリデーションチェックはフロントエンド側とサーバーサイド側の両方で行うことが一般的です。

ここではフロントエンド側のバリデーションチェックとして、 HTML で実装できるものをご紹介します。

バリデーションチェックの種類

バリデーションチェックは、具体的には以下のようなことを行います。

必須フィールドのバリデーション

入力フォームが空白でないことを確認するために行います。

HTML で実装する場合、フォーム部品に対して required 属性を指定します。 required 属性を指定した要素の入力値が空の場合、送信は行われずにアラートが表示されます。

<input required>

データ形式のバリデーション

データが特定の形式に従っているかどうかをチェックします。例として、メールアドレスに対するバリデーションチェックでは主に、

  • 「@」の記述があるか
  • 「@」の前に半角英数字が記述されているか
  • 「@」の後に半角英数字が記述されているか
  • 「.」の記述位置が正しいか
  • メールアドレスに使用できる文字列か

などのチェックを行います。

HTMLで実装する場合、 type 属性を指定します。「 type=”email” 」を指定することで、上記に挙げたバリデーションチェックが実装されます。

<input type="email">

文字数や値の範囲のバリデーション

入力された値に文字の最大数・最小数や、値の最大値・最小値といった制限を設定し、制限内で入力されているかどうかをチェックします。

HTMLで実装する場合は以下の属性を指定します。

  • 文字の最大数:maxlength
  • 文字の最小数:minlength
  • 値の最大値:max
  • 値の最小値:min

type=”text” type=”password” textarea などのテキストフィールドには maxlength minlength を指定します。

また、 type=”number” など数値を扱うフォーム部品には max min を指定します。

<input type="text" minlength="2" maxlength="30">
<input type="number" min="18" max="70">

minlength の条件を満たしていなければ以下のように表示されます。また、 maxlength の設定値以上は文字の入力ができなくなくなります。

お問い合わせフォームにバリデーションチェックを追加しよう

前回までの記事で制作したお問い合わせフォームには type 属性や require 属性の指定を行っているので、実は基本的なバリデーションチェックは実装できています。

ここでは、更にバリデーションを追加して、バリデーションチェックの実装に関する基本的な考え方を学んでいきます。

今回追加するバリデーションは以下です。

  • お名前とお問い合わせ内容の文字数を制限する
  • お名前入力欄のフォーマットを定義する
  • 性別の選択を必須にする

それでは始めます。

前回までのHTMLのサンプルコード

前回までの記事でHTMLは以下のようになっています。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>お問い合わせ</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <header>
    <h1>LOGO</h1>
  </header>

  <main>
    <h2>お問い合わせ</h2>
    <form id="form" action="" method="GET">

      <div class="form-item">
        <label for="type" class="form-ttl">お問い合わせの種類</label>
        <div class="select-wrap">
          <select id="type" name="type">
            <option value="learn" selected>ウェブ制作の学び方について</option>
            <option value="article">記事の内容について</option>
            <option value="site">このサイトの使い方について</option>
            <option value="admin">このサイトの管理者について</option>
          </select>
        </div>
      </div>

      <div class="form-item">
        <label for="name" class="form-ttl">お名前<span class="required">必須</span></label>
        <p class="example-txt">例:山田 太郎</p>
        <input type="text" id="name" name="name" required>
      </div>

      <div class="form-item">
        <fieldset>
          <legend class="form-ttl">性別</legend>
          <label for="male"><input type="radio" id="male" name="gender" value="male">男性</label>
          <label for="female"><input type="radio" id="female" name="gender" value="female">女性</label>
        </fieldset>
      </div>

      <div class="form-item">
        <label for="email" class="form-ttl">メールアドレス<span class="required">必須</span></label>
        <p class="example-txt">例:hogehoge@example.com</p>
        <input type="mail" id="email" name="email" required>
      </div>

      <div class="form-item">
        <fieldset>
          <legend class="form-ttl">学習中の言語</legend>
          <label for="html"><input type="checkbox" id="html" name="learning" value="html" checked>HTML</label>
          <label for="css"><input type="checkbox" id="css" name="learning" value="css">CSS</label>
          <label for="javascript"><input type="checkbox" id="javascript" name="learning" value="javascript">JavaScript</label>
          <label for="php"><input type="checkbox" id="php" name="learning" value="php">PHP</label>
        </fieldset>
      </div>

      <div class="form-item">
        <label for="content" class="form-ttl">お問い合わせ内容<span class="required">必須</span></label>
        <textarea id="content" name="content" rows="20" required></textarea>
      </div>

      <div class="policy-check-wrap">
        <label for="policy-check">
          <input
            type="checkbox"
            id="policy-check"
            name="policy-check"
            required>個人情報保護方針に同意します。
        </label>
      </div>

      <div class="btn-wrap">
        <button type="submit" id="submit">お問い合わせ内容を送信</button>
      </div>

    </form>
  </main>

  <footer>&copy;copyright.</footer>
</body>
</html>

まずは、お名前とお問い合わせ内容の文字数を制限します。

お名前とお問い合わせ内容の文字数を制限する

お名前入力欄とお問い合わせ内容入力欄はテキストフィールドなので、 maxlength minlength を指定することで文字数の制限を行うことができます。

お名前の入力欄は以下のように記述します。

<label for="name" class="form-ttl">お名前<span class="required">必須</span></label>
<p class="example-txt">例:山田 太郎</p>
<input
  type="text"
  id="name"
  name="name"
  required
  minlength="3"
  maxlength="100">

「 minlength=”3 “」「 maxlength=”100″ 」を追記しました。コードを見やすくするために属性を改行していますがお好みで構いません。

minlength maxlength の値は入力例に基づいて考えることができます。

お名前入力欄の入力例は「山田 太郎」となっています。これは、苗字と名前をフルネームで入力してもらう意図であることが分かります。

ユーザーが日本人や中国人である場合、苗字と名前がそれぞれ漢字一文字であることは十分にあり得るでしょう。スペースも文字数としてカウントされるので、最低で苗字一文字、スペース、名前一文字を入力してもらうために minlength の値は「 3 」としています。

また、 maxlength の値は悪意あるユーザーからの入力を簡易的に防ぐ役割を果たします。悪意あるユーザーはサーバーに付加を掛ける目的(DoS攻撃)で、膨大なデータを入力するなど意図しない値を送信してくる可能性があります。

maxlength を設定しておくことで過剰な入力を簡易的に防ぐことができるので、指定しておくと良いでしょう。

maxlengthによるDoS攻撃対策はあくまで簡易的なものです。

HTML側で行うバリデーションチェックはブラウザの開発ツールから簡単に改ざんできてしまうため、セキュリティ対策としての効果はほとんど期待できません。

適切なセキュリティ対策はサーバーサイド側で行う必要があり、maxlengthの指定はそれを補助する役割として機能します。

続いて、お問い合わせ内容の入力欄は以下のように記述します。

<label for="content" class="form-ttl">お問い合わせ内容<span class="required">必須</span></label>
<textarea
  id="content"
  name="content"
  rows="20"
  required
  maxlength="1000"></textarea>

「 maxlength=”1000″ 」を追記しました。

お名前入力欄と同様に簡易的なセキュリティ対策の意図もありますが、単純にサーバーの負荷を考えて最大文字数を制限することもあります。

ここでは最大文字数を1000文字と定義していますが、想定されるお問い合わせの内容によって調整する必要があります。

お問い合わせ内容はユーザーにとってのお問い合わせフォームを利用する目的にあたるので、過剰な制限はユーザビリティを損なう恐れがあるため注意しましょう。

お名前入力欄のフォーマットを定義する

お名前入力欄の入力例は「山田 太郎」となっています。

また、お名前入力欄の入力は最低で苗字一文字、スペース、名前一文字を入力してもらうために最低文字数を3文字と指定しました。

しかし、このバリデーションチェックはあくまで文字数にしか作用しないため、意図しない入力を許容します。つまり、文字数が3文字以上であれば苗字だけや名前だけの入力も許容されます。

ここでは、入力できる値をより入力例に近づけるために以下の実装を行います。

  • 文字と文字の間に必ず1つのスペースがあるかを判定
  • 漢字、ひらがな、カタカナ、半角アルファベット、スペース以外は入力不可

これらのバリデーションを行うことで、お名前入力欄に入力できる値をより入力例に近づけることができます。

これらは pattern 属性を使用することで実装できます。 pattern 属性は入力値のフォーマットを定義するための属性です。以下のように記述します。

<label for="name" class="form-ttl">お名前<span class="required">必須</span></label>
<p class="example-txt">例:山田 太郎</p>
<input
  type="text"
  id="name"
  name="name"
  required
  minlength="3"
  maxlength="100"
  pattern="^[\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Han}a-zA-Z]+\s[\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Han}a-zA-Z]+$"
>

pattern 属性の値は正規表現という記法で記述します。正規表現を初めて目にする方は戸惑うかもしれませんが、バリデーションチェックの実装では無視できない存在です。

正規表現についての詳しい説明は割愛しますが、テキストのパターンを表現するための記法とだけ認識しておけばとりあえず問題ありません。

一般的によく使われるバターンはある程度決まっているので、必要に応じて調べると良いでしょう。

これで名前入力に関するフォーマットを定義することができました。入力値を「山田太郎」として送信するとバリデーションが機能していることが分かります。

性別の選択を必須にする

性別の選択肢はラジオボタンで実装しています。ラジオボタンの選択を必須にする方法は簡単で、選択肢のいずれかに required 属性を指定することで実装できます。

<legend class="form-ttl">性別</legend>
<!-- 片方にrequired指定で機能します -->
<label for="male">
  <input
    type="radio"
    id="male"
    name="gender"
    value="male"
    required>男性</label>
<label for="female">
  <input
    type="radio"
    id="female"
    name="gender"
    value="female">女性</label>

ここでは男性に required 属性を指定しましたが、女性に指定しても動作します。また、両方に指定しても問題ありません。

これで性別の選択を必須にすることができました。性別が選択されていない場合は以下のようにアラートが表示されます。

チェックボックスの選択を必須にする方法について

チェックボックスとラジオボタンは記述がほとんど同じなので、同じ方法でチェックボックスも選択を必須にできると考えるかもしれません。

しかし、チェックボックスにrequired属性を指定しても、実際はrequire属性を指定した項目の選択が必須になるだけで、同じグループのいずれかの選択を必須にするようなことをHTMLで実装することはできません。

例えば、このお問い合わせフォームの「学習中の言語」選択欄ではチェックボックスを使用していますが、HTMLにrequired属性を指定するとHTMLの選択のみが必須になり、HTMLが選択されていなければCSS、JavaScript、PHPの項目が選択されていたとしてもフォームを送信することができなくなります。

これを適切に動作させるにはJavaScriptで制御する必要があります。興味のある方は調べてみると良いでしょう。

HTMLでのバリデーションチェックの実装を行いました。全体のコードは以下です。

サンプルコードの全体

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>お問い合わせ</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <header>
    <h1>LOGO</h1>
  </header>

  <main>
    <h2>お問い合わせ</h2>
    <form id="form" action="" method="GET">

      <div class="form-item">
        <label for="type" class="form-ttl">お問い合わせの種類</label>
        <div class="select-wrap">
          <select id="type" name="type">
            <option value="learn" selected>ウェブ制作の学び方について</option>
            <option value="article">記事の内容について</option>
            <option value="site">このサイトの使い方について</option>
            <option value="admin">このサイトの管理者について</option>
          </select>
        </div>
      </div>

      <div class="form-item">
        <label for="name" class="form-ttl">お名前<span class="required">必須</span></label>
        <p class="example-txt">例:山田 太郎</p>
        <input
          type="text"
          id="name"
          name="name"
          required
          minlength="3"
          maxlength="100"
          pattern="^[\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Han}a-zA-Z]+\s[\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Han}a-zA-Z]+$">
      </div>

      <div class="form-item">
        <fieldset>
          <legend class="form-ttl">性別</legend>
          <label for="male">
            <input
              type="radio"
              id="male"
              name="gender"
              value="male"
              required>男性</label>
          <label for="female">
            <input
              type="radio"
              id="female"
              name="gender"
              value="female">女性</label>
        </fieldset>
      </div>

      <div class="form-item">
        <label for="email" class="form-ttl">メールアドレス<span class="required">必須</span></label>
        <p class="example-txt">例:hogehoge@example.com</p>
        <input type="mail" id="email" name="email" required>
      </div>

      <div class="form-item">
        <fieldset>
          <legend class="form-ttl">学習中の言語</legend>
          <label for="html"><input type="checkbox" id="html" name="learning" value="html" checked>HTML</label>
          <label for="css"><input type="checkbox" id="css" name="learning" value="css">CSS</label>
          <label for="javascript"><input type="checkbox" id="javascript" name="learning" value="javascript">JavaScript</label>
          <label for="php"><input type="checkbox" id="php" name="learning" value="php">PHP</label>
        </fieldset>
      </div>

      <div class="form-item">
        <label for="content" class="form-ttl">お問い合わせ内容<span class="required">必須</span></label>
        <textarea
          id="content"
          name="content"
          rows="20"
          required
          maxlength="1000"></textarea>
      </div>

      <div class="policy-check-wrap">
        <label for="policy-check">
          <input
            type="checkbox"
            id="policy-check"
            name="policy-check"
            required>個人情報保護方針に同意します。
        </label>
      </div>

      <div class="btn-wrap">
        <button type="submit" id="submit">お問い合わせ内容を送信</button>
      </div>

    </form>
  </main>

  <footer>&copy;copyright.</footer>
</body>
</html>

最後に

バリデーションチェックの概要を学び、ここまで作成してきたお問い合わせフォームのHTML要素に属性を追加し、バリデーションチェックの実装を行いました。

HTMLで実装したバリデーションチェックは、エラー文やデザインがブラウザによって違い、HTMLのみでは変更することができません。また、ユーザーは一度送信ボタンをクリックするまで入力が正しいかどうかが分からないという不便さもあります。

次のステップの「お問い合わせフォームを作ってみよう【バリデーションチェック編(JavaScript)】」では、JavaScriptを使用したバリデーションチェックの方法について解説します。

JavaScriptを使用することで、エラーメッセージのデザインやチェックのタイミング制御など、より柔軟な対応が可能になります。

少し難易度が高くなりますが、JavaScriptでのバリデーションチェックの実装は一般的な手法であり、ウェブ制作初心者の方にとってはJavaScriptの理解を深める良いきっかけになります。ぜひ参考にしてください。

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