Blog スタッフブログ

JavaScript WEB制作

[WordPress]Contact Form 7にJavaScriptで確認画面を追加する方法

WordPressのメールフォームプラグイン「Contact Form 7」には、標準では入力内容の確認画面が用意されていません。

今回は、追加プラグインやページ遷移を使わず、JavaScriptで同一ページ内に疑似的な確認画面を表示する方法を紹介します。

フォームの動きは次のとおりです。

  • 1. ユーザーがフォームへ入力する
  • 2. 「入力内容のご確認」を押す
  • 3. 入力フォームを非表示にする
  • 4. 入力内容を確認画面へ表示する
  • 5. 「入力内容を修正する」を押すと入力画面へ戻る
  • 6. 「送信する」を押すとContact Form 7が通常どおり送信する

入力画面と確認画面は同じContact Form 7のフォーム内に配置します。

確認画面を表示している間も元のフォーム項目は削除せず、非表示にするだけです。そのため、確認画面から送信しても、Contact Form 7へ元の入力値がそのまま渡されます。

手順

Contact Form 7のフォームを作成する

Contact Form 7の管理画面を開き以下のようにフォームを作成します。

■例

<div class="contactForm">
    <div class="js-contact-form">
        <!-- 入力画面 -->
        <div class="contactInput js-contact-input">
            <table>
                <tr>
                    <th>
                        お名前<span class="required">必須</span>
                    </th>
                    <td>
                        [text* your-name class:form-control placeholder "山田 太郎"]
                    </td>
                </tr>
                <tr>
                    <th>
                        会社名<span class="required">必須</span>
                    </th>
                    <td>
                        [text* your-company class:form-control placeholder "〇〇株式会社"]
                    </td>
                </tr>
                <tr>
                    <th>
                        メールアドレス<span class="required">必須</span>
                    </th>
                    <td>
                        [email* your-email class:form-control placeholder "example@example.com"]
                    </td>
                </tr>
                <tr>
                    <th>
                        電話番号<span class="required">必須</span>
                    </th>
                    <td>
                        [tel* your-tel class:form-control placeholder "09012345678"]
                    </td>
                </tr>
                <tr>
                    <th>
                        お問い合わせ内容<span class="required">必須</span>
                    </th>
                    <td>
                        [textarea* content class:form-control]
                    </td>
                </tr>
            </table>
            <div class="formBtn">
                <button type="button" class="js-contact-confirm">
                    入力内容のご確認
                </button>
            </div>
        </div>

        <!-- 確認画面 -->
        <div class="contactConfirm js-contact-confirm-screen" hidden>
            <p class="contactConfirm__message">
                入力内容をご確認の上、「送信する」ボタンを押してください。
            </p>
            <table>
                <tr>
                    <th>お名前</th>
                    <td class="js-confirm-your-name"></td>
                </tr>
                <tr>
                    <th>会社名</th>
                    <td class="js-confirm-your-company"></td>
                </tr>
                <tr>
                    <th>メールアドレス</th>
                    <td class="js-confirm-your-email"></td>
                </tr>
                <tr>
                    <th>電話番号</th>
                    <td class="js-confirm-your-tel"></td>
                </tr>
                <tr>
                    <th>お問い合わせ内容</th>
                    <td class="js-confirm-content"></td>
                </tr>
            </table>
            <div class="formBtn formBtn--confirm">
                <button type="button" class="js-contact-back">
                    入力内容を修正する
                </button>
                [submit class:js-contact-submit "送信する"]
            </div>
        </div>
    </div>
</div>

確認画面を切り替えるJavaScript

テーマのJavaScriptファイルへ、次のコードを追加します。

今回はjQueryを使用しています。

jQuery(function ($) {
  $(".js-contact-form").each(function () {
    const $contactForm = $(this);
    const $cf7Form = $contactForm.closest("form.wpcf7-form");
    const $wpcf7 = $contactForm.closest(".wpcf7");

    const $inputScreen = $contactForm.find(".js-contact-input");
    const $confirmScreen = $contactForm.find(
      ".js-contact-confirm-screen"
    );

    const $confirmButton = $contactForm.find(
      ".js-contact-confirm"
    );

    const $backButton = $contactForm.find(
      ".js-contact-back"
    );

    /*
     * 必要な要素が存在しない場合は処理を終了する
     */
    if (
      !$cf7Form.length ||
      !$inputScreen.length ||
      !$confirmScreen.length ||
      !$confirmButton.length
    ) {
      return;
    }

    /**
     * name属性からフォーム項目を取得する
     */
    function getField(name) {
      return $cf7Form.find('[name="' + name + '"]');
    }

    /**
     * フォーム項目の値を取得する
     */
    function getValue(name) {
      const $field = getField(name);

      if (!$field.length) {
        return "";
      }

      /*
       * ラジオボタンとチェックボックスの場合
       */
      if ($field.is(":radio") || $field.is(":checkbox")) {
        const values = $field
          .filter(":checked")
          .map(function () {
            return $(this).val();
          })
          .get();

        return values.join("、");
      }

      /*
       * selectが複数選択の場合
       */
      if ($field.is("select[multiple]")) {
        return ($field.val() || []).join("、");
      }

      return $.trim($field.val() || "");
    }

    /**
     * 確認画面へ入力内容を表示する
     */
    function setConfirmValues() {
      $contactForm
        .find(".js-confirm-your-name")
        .text(getValue("your-name"));

      $contactForm
        .find(".js-confirm-your-company")
        .text(getValue("your-company"));

      $contactForm
        .find(".js-confirm-your-email")
        .text(getValue("your-email"));

      $contactForm
        .find(".js-confirm-your-tel")
        .text(getValue("your-tel"));

      $contactForm
        .find(".js-confirm-content")
        .text(getValue("content"));
    }

    /**
     * フォームの先頭へスクロールする
     */
    function scrollToForm() {
      const headerOffset = 120;

      $("html, body")
        .stop(true)
        .animate(
          {
            scrollTop:
              $contactForm.offset().top - headerOffset
          },
          400
        );
    }

    /**
     * 確認画面を表示する
     */
    function showConfirmScreen() {
      setConfirmValues();

      $inputScreen.attr("hidden", true);
      $confirmScreen.removeAttr("hidden");

      $contactForm.addClass("is-confirm");

      scrollToForm();
    }

    /**
     * 入力画面を表示する
     */
    function showInputScreen() {
      $confirmScreen.attr("hidden", true);
      $inputScreen.removeAttr("hidden");

      $contactForm.removeClass("is-confirm");

      scrollToForm();
    }

    /**
     * 「入力内容のご確認」をクリック
     */
    $confirmButton.on("click", function () {
      showConfirmScreen();
    });

    /**
     * 「入力内容を修正する」をクリック
     */
    $backButton.on("click", function () {
      showInputScreen();
    });

    /**
     * Contact Form 7で入力エラーになった場合
     */
    document.addEventListener(
      "wpcf7invalid",
      function (event) {
        if (
          !$wpcf7.length ||
          event.target !== $wpcf7.get(0)
        ) {
          return;
        }

        showInputScreen();
      },
      false
    );

    /**
     * メール送信に失敗した場合
     */
    document.addEventListener(
      "wpcf7mailfailed",
      function (event) {
        if (
          !$wpcf7.length ||
          event.target !== $wpcf7.get(0)
        ) {
          return;
        }

        showInputScreen();
      },
      false
    );

    /**
     * 迷惑メールと判定された場合
     */
    document.addEventListener(
      "wpcf7spam",
      function (event) {
        if (
          !$wpcf7.length ||
          event.target !== $wpcf7.get(0)
        ) {
          return;
        }

        showInputScreen();
      },
      false
    );

    /**
     * 送信成功後
     */
    document.addEventListener(
      "wpcf7mailsent",
      function (event) {
        if (
          !$wpcf7.length ||
          event.target !== $wpcf7.get(0)
        ) {
          return;
        }

        $confirmScreen.attr("hidden", true);
        $inputScreen.removeAttr("hidden");

        $contactForm.removeClass("is-confirm");
      },
      false
    );

    /**
     * 初期表示
     */
    $confirmScreen.attr("hidden", true);
    $inputScreen.removeAttr("hidden");
  });
});

JavaScriptの処理内容

以下の部分はフォームの項目に応じて変更必要です。

function setConfirmValues() {
      $contactForm
        .find(".js-confirm-your-name")
        .text(getValue("your-name"));

      $contactForm
        .find(".js-confirm-your-company")
        .text(getValue("your-company"));

      $contactForm
        .find(".js-confirm-your-email")
        .text(getValue("your-email"));

      $contactForm
        .find(".js-confirm-your-tel")
        .text(getValue("your-tel"));

      $contactForm
        .find(".js-confirm-content")
        .text(getValue("content"));
    }

実装の要点は次のとおりです。

* 入力画面と確認画面を同じContact Form 7内に配置する

* 確認画面は初期状態で非表示にする

* 入力値を `name` 属性から取得する

* 取得した値は `text()` で確認画面へ出力する

* 入力画面は削除せず、`hidden` 属性で非表示にする

* 修正ボタンで入力画面へ戻す

* Contact Form 7の送信エラー時にも入力画面へ戻す

* 複数フォームがある場合はイベントの発生元を判定する

* 項目数が多い場合は `data-confirm` 属性で対応関係を管理する

この方法なら、別ページへの値の引き継ぎや追加プラグインを使用せず、比較的シンプルな構成で確認画面を追加できます。