Astro製サイトにSSGformを設置する(2)フォームのバリデーション

Web関連情報・技術

当サイトにはプロモーション・広告が含まれています。

Static Site Generator(静的サイトジェネレーター)をはじめ、WordPressやその他Webサイトでも利用可能なSSGform。フォーム送信自体は<form>action要素の値にSSGformのコードを入れるだけで可能である。

前の記事:Astro製サイトにSSGformを設置する(1)reCAPTCHAの設定

今回は、実際のフォームのマークアップとバリデーションについて説明したい。

HTML

<form class="form" id="form" action="https://ssgform.com/s/(SSGformのコード)" method="post" novalidate>
  <div class="form__cont">
    <label class="form__label" for="name">お名前
      <span class="form__required">必須</span>
    </label>
    <div class="form__contInner">
      <input class="form__text" type="text" id="name" name="name" placeholder="すずなつ太郎" aria-required="true" required>
    </div>
  </div>
  <div class="form__cont">
    <label class="form__label" for="email">メールアドレス
      <span class="form__required">必須</span>
    </label>
    <div class="form__contInner">
      <input class="form__text" type="email" autocomplete="email" id="email" name="email" placeholder="[email protected]" aria-required="true" required>
      <span class="form__errorMessage text-red-500 text-xs">
      </span>
    </div>
  </div>
  <div class="form__cont">
    <label class="form__label" for="message">お問い合わせ内容
      <span class="form__required">必須</span>
    </label>
    <div class="form__contInner">
      <textarea class="form__textarea" id="message" name="message" cols="30" rows="10" placeholder="お問い合わせ内容をご記入ください" aria-required="true" required>
      </textarea>
    </div>
  </div>
  <script is:inline src="https://www.google.com/recaptcha/api.js" async defer></script>
  <div class="g-recaptcha mt-4 flex justify-center" data-sitekey="(reCAPTCHAのコード)">
  </div>
  <button type="submit" class="form__btn is-disabled" disabled>送信する</button>
</form>

当サイトの場合は、

  • 名前
  • メールアドレス
  • 問い合わせ内容(本文)

の3項目と非常にシンプルな構成になっている。全項目必須なので、各入力エリアにはaria-required="true"requiredを付与した。

Web API標準のポップアップによるエラーを表示させたくないので、form要素にnovalidate属性を付けた。

JavaScript

Web APIを用いたバリデーションチェックを行う。

// フォームの各パーツ
const formBtn = document.querySelector(".form__btn");
const person = document.querySelector("input[name='name']");
const email = document.querySelector("input[name='email']");
const message = document.querySelector("textarea[name='message']");
// エラーメッセージエリア
const errorMessage = document.querySelector(".form__errorMessage");

// Web API でメールアドレスをチェック
// バリデーションの初期化
const resetValidation = () => {
  email.setCustomValidity("");
  email.classList.remove("is-invalid");
  errorMessage.textContent = "";
};
const validateEmail = () => {
  if (email.validity.typeMismatch) {
    // カスタムバリデーション
    email.setCustomValidity("正しいメールアドレスを入力してください");
    email.classList.add("is-invalid");
    errorMessage.textContent = email.validationMessage;
  } else {
    // バリデーションを通ったとき
    resetValidation();
  }
  // バリデーションメッセージを表示
  email.checkValidity(); 
};

const validateForm = () => {
  const personVal = person.value.trim();
  const emailVal = email.value.trim();
  const messageVal = message.value.trim();

  // 各項目の入力とメールアドレスのチェック
  const isFormFilled = personVal !== "" && emailVal !== "" && messageVal !== "";
  const isEmailValid = email.checkValidity();

  if (emailVal !== "") {
    validateEmail();
  }
  if (isFormFilled && isEmailValid) {
    formBtn.classList.remove("is-disabled");
    formBtn.disabled = false;
  } else {
    formBtn.classList.add("is-disabled");
    formBtn.disabled = true;
  }
};

// 入力されたときにバリデーションが発動する
person.oninput = validateForm;
email.oninput = validateForm;
message.oninput = validateForm;

当フォームは項目数が少ないので、全項目が正しく入力されていなければ送信できない(=正しく入力されたら「送信」ボタンが活性化する)ようにした。

メールアドレスのパターンチェック

メールアドレス欄のみ入力パターンをチェックし、メールのパターンに合致しない場合はエラーメッセージが出るようにする。バリデーションにはWeb API標準の機能を使用。

標準のバリデーション文言「メール アドレスに「@」を挿入してください。「aaa」内に「@」がありません。」を使いたくないので、setCustomValidity()でカスタムの文言にした。

email.validity.typeMismatchでメールアドレスのパターンチェックを行っている。

validityプロパティでValidityStateオブジェクト(input要素の検証状態に関する情報)にアクセスし、typeMismatchプロパティでemailurlの値をチェックする。

Web APIを用いたバリデーションチェックは、メールアドレスパターン(/^[^\s@]+@[^\s@]+\.[^\s@]+$/みたいなやつ)をいちいち書かない点は楽かも。

参考ページ

☕コーヒーをおごる

Buy Me A Coffee

このブログについて

コーディングやWeb関連技術の記事と、買い物など日々のメモから成り立っています。 →少しだけ詳しく

広告