Written by Toshiki

プラグイン不要でContact Form 7の確認画面と送信完了ページを実装する

JavaScript Web制作 WordPress

こんにちは、トシキです。
今回は、プラグインを使わずにContact Form 7の確認画面と送信完了ページ(サンクスページ)を実装する方法について書いていきます。
本記事は、しょーごさんの以下の記事を参考にし、自分用に改良を加えたものになります。

しょーごさんの他の記事では、Contact Form 7の基本的な使い方や、プラグインの「Contact Form 7 Multi-Step Forms」を使った確認画面の実装方法についても解説されています。詳しく知りたい方はぜひ読んでみてください。

本記事の内容

スポンサードサーチ

プラグイン不要でContact Form 7の確認画面と送信完了ページを実装する

以下が実装するフォームのサンプルです。
必須項目を入力し、「同意する(承認確認)」にチェックを入れると、「確認する」ボタンが押せるようになります。左がPC、右がスマホで閲覧した場合の表示です。

確認画面↓

セレクトボックスを複数選択可能にした場合にも対応しています↓

1-01. HTML


<div class="ly_form" id="js_form">
  <!-- Contact Form 7に貼り付ける部分ここから↓ -->
  <!-- 入力画面 -->
  <div class="bl_form">
    <div class="bl_form_group">
      <label class="bl_form_label" for="name">お名前<span class="bl_form_required" aria-hidden="true">必須</span></label>
      <div class="bl_form_control">
        [text* your_name id:name]
      </div>
    </div>
    <div class="bl_form_group">
      <label class="bl_form_label" for="email">メールアドレス<span class="bl_form_required" aria-hidden="true">必須</span></label>
      <div class="bl_form_control">
        [email* email id:email]
      </div>
    </div>
    <div class="bl_form_group">
      <label class="bl_form_label" for="tel">電話番号</label>
      <div class="bl_form_control">
        [tel tel id:tel placeholder "012-3456-7890"]
      </div>
    </div>
    <div class="bl_form_group">
      <label class="bl_form_label" for="message">お問い合わせ内容</label>
      <div class="bl_form_control">
        [textarea message id:message placeholder "詳細をご記入ください"]
      </div>
    </div>
    <div class="bl_form_group">
      <fieldset>
        <legend class="bl_form_label">ラジオボタン</legend>
        <div class="bl_form_control">
          [radio radio id:radio class:bl_form_radio use_label_element default:1 "ラジオボタン1" "ラジオボタン2" "ラジオボタン3"]
        </div>
      </fieldset>
    </div>
    <div class="bl_form_group">
      <fieldset>
        <legend class="bl_form_label">チェックボックス</legend>
        <div class="bl_form_control">
          [checkbox checkbox id:checkbox class:bl_form_checkbox use_label_element "チェックボックス1" "チェックボックス2" "チェックボックス3"]
        </div>
      </fieldset>
    </div>
    <div class="bl_form_group">
      <label class="bl_form_label" for="select">セレクトボックス</label>
      <div class="bl_form_control">
        [select select id:select include_blank "セレクト1" "セレクト2" "セレクト3"]
      </div>
    </div>
    <div class="bl_form_group">
      <label class="bl_form_label" for="file">アップロードファイル</label>
      <div class="bl_form_control">
        [file file id:file]
      </div>
    </div>
    <div class="bl_form_consent">
      <p class="bl_form_consent_desc">「<a class="bl_form_consent_desc_link" href="#">プライバシーポリシー</a>」をご確認いただき、同意のうえ送信してください。</p>
      [acceptance acceptance id:consent] 同意する [/acceptance]
    </div>
    <div class="bl_form_btn"><input class="bl_form_confirm" type="button" value="確認する" disabled></div>
  </div>

  <!-- 確認画面 -->
  <div class="bl_formConfirm">
    <p class="bl_formConfirm_txt">以下の内容でよろしいですか?</p>
    <div class="bl_form_group">
      <p class="bl_form_label">お名前</p>
      <div class="bl_form_control">
        <p class="bl_confirm_name"></p>
      </div>
    </div>
    <div class="bl_form_group">
      <p class="bl_form_label">メールアドレス</p>
      <div class="bl_form_control">
        <p class="bl_confirm_email"></p>
      </div>
    </div>
    <div class="bl_form_group">
      <p class="bl_form_label">電話番号</p>
      <div class="bl_form_control">
        <p class="bl_confirm_tel"></p>
      </div>
    </div>
    <div class="bl_form_group">
      <p class="bl_form_label">お問い合わせ内容</p>
      <div class="bl_form_control">
        <p class="bl_confirm_message"></p>
      </div>
    </div>
    <div class="bl_form_group">
      <p class="bl_form_label">ラジオボタン</p>
      <div class="bl_form_control">
        <p class="bl_confirm_radio"></p>
      </div>
    </div>
    <div class="bl_form_group">
      <p class="bl_form_label">チェックボックス</p>
      <div class="bl_form_control">
        <p class="bl_confirm_checkbox"></p>
      </div>
    </div>
    <div class="bl_form_group">
      <p class="bl_form_label">セレクトボックス</p>
      <div class="bl_form_control">
        <p class="bl_confirm_select"></p>
      </div>
    </div>
    <div class="bl_form_group">
      <p class="bl_form_label">アップロードファイル</p>
      <div class="bl_form_control">
        <p class="bl_confirm_file"></p>
      </div>
    </div>
    <div class="bl_form_group">
      <p class="bl_form_label">プライバシーポリシー</p>
      <div class="bl_form_control">
        <p class="bl_confirm_consent"></p>
      </div>
    </div>
    <div class="bl_form_btn">
      <input type="button" class="bl_form_back" value="戻る">
      [submit class:bl_form_submit "送信する"]
    </div>
  </div>
  <!-- Contact Form 7に貼り付ける部分ここまで↑ -->
</div>

Contact Form 7のタグがHTMLで出力された状態


<div class="ly_form" id="js_form">
  <!-- Contact Form 7に貼り付ける部分ここから↓ -->
  <!-- 入力画面 -->
  <div class="bl_form">
    <div class="bl_form_group">
      <label class="bl_form_label" for="name">お名前<span class="bl_form_required" aria-hidden="true">必須</span></label>
      <div class="bl_form_control">
        <!-- CF7のHTMLここから -->
        <span class="wpcf7-form-control-wrap">
          <input size="40" class="wpcf7-form-control wpcf7-text wpcf7-validates-as-required" id="name" aria-required="true" aria-invalid="false" value="" type="text" name="your_name">
          <span class="wpcf7-not-valid-tip" aria-hidden="true">入力してください。</span>
        </span>
        <!-- CF7のHTMLここまで -->
      </div>
    </div>
    <div class="bl_form_group">
      <label class="bl_form_label" for="email">メールアドレス<span class="bl_form_required" aria-hidden="true">必須</span></label>
      <div class="bl_form_control">
        <!-- CF7のHTMLここから -->
        <span class="wpcf7-form-control-wrap">
          <input size="40" class="wpcf7-form-control wpcf7-email wpcf7-validates-as-required wpcf7-text wpcf7-validates-as-email" id="email" aria-required="true" aria-invalid="false" value="" type="email" name="email">
        </span>
        <!-- CF7のHTMLここまで -->
      </div>
    </div>
    <div class="bl_form_group">
      <label class="bl_form_label" for="tel">電話番号</label>
      <div class="bl_form_control">
        <!-- CF7のHTMLここから -->
        <span class="wpcf7-form-control-wrap">
          <input size="40" class="wpcf7-form-control wpcf7-tel wpcf7-text wpcf7-validates-as-tel" id="tel" aria-invalid="false" placeholder="012-3456-7890" value="" type="tel" name="tel">
        </span>
        <!-- CF7のHTMLここまで -->
      </div>
    </div>
    <div class="bl_form_group">
      <label class="bl_form_label" for="message">お問い合わせ内容</label>
      <div class="bl_form_control">
        <!-- CF7のHTMLここから -->
        <span class="wpcf7-form-control-wrap">
          <textarea cols="40" rows="10" class="wpcf7-form-control wpcf7-textarea" id="message" aria-invalid="false" placeholder="詳細をご記入ください" name="message"></textarea>
        </span>
        <!-- CF7のHTMLここまで -->
      </div>
    </div>
    <div class="bl_form_group">
      <fieldset>
        <legend class="bl_form_label">ラジオボタン</legend>
        <div class="bl_form_control">
          <!-- CF7のHTMLここから -->
          <span class="wpcf7-form-control-wrap" data-name="radio">
            <span class="wpcf7-form-control wpcf7-radio bl_form_radio" id="radio">
              <span class="wpcf7-list-item first">
                <label>
                  <input type="radio" name="radio" value="ラジオボタン1" checked="checked" />
                  <span class="wpcf7-list-item-label">ラジオボタン1</span>
                </label>
              </span>
              <span class="wpcf7-list-item">
                <label>
                  <input type="radio" name="radio" value="ラジオボタン2" />
                  <span class="wpcf7-list-item-label">ラジオボタン2</span>
                </label>
              </span>
              <span class="wpcf7-list-item last">
                <label>
                  <input type="radio" name="radio" value="ラジオボタン3" />
                  <span class="wpcf7-list-item-label">ラジオボタン3</span>
                </label>
              </span>
            </span>
          </span>
          <!-- CF7のHTMLここまで -->
        </div>
      </fieldset>
    </div>
    <div class="bl_form_group">
      <fieldset>
        <legend class="bl_form_label">チェックボックス</legend>
        <div class="bl_form_control">
          <!-- CF7のHTMLここから -->
          <span class="wpcf7-form-control-wrap" data-name="checkbox">
            <span class="wpcf7-form-control wpcf7-checkbox bl_form_checkbox" id="checkbox">
              <span class="wpcf7-list-item first">
                <label>
                  <input type="checkbox" name="checkbox[]" value="チェックボックス1" />
                  <span class="wpcf7-list-item-label">チェックボックス1</span>
                </label>
              </span>
              <span class="wpcf7-list-item">
                <label>
                  <input type="checkbox" name="checkbox[]" value="チェックボックス2" />
                  <span class="wpcf7-list-item-label">チェックボックス2</span>
                </label>
              </span>
              <span class="wpcf7-list-item last">
                <label>
                  <input type="checkbox" name="checkbox[]" value="チェックボックス3" />
                  <span class="wpcf7-list-item-label">チェックボックス3</span>
                </label>
              </span>
            </span>
          </span>
          <!-- CF7のHTMLここまで -->
        </div>
      </fieldset>
    </div>
    <div class="bl_form_group">
      <label class="bl_form_label" for="select">セレクトボックス</label>
      <div class="bl_form_control">
        <!-- CF7のHTMLここから -->
        <span class="wpcf7-form-control-wrap">
          <select class="wpcf7-form-control wpcf7-select" id="select" aria-invalid="false" name="select">
            <option value="選択して下さい">選択して下さい</option>
            <option value="セレクト1">セレクト1</option>
            <option value="セレクト2">セレクト2</option>
            <option value="セレクト3">セレクト3</option>
          </select>
        </span>
        <!-- CF7のHTMLここまで -->
      </div>
    </div>
    <div class="bl_form_group">
      <label class="bl_form_label" for="file">アップロードファイル</label>
      <div class="bl_form_control">
        <!-- CF7のHTMLここから -->
        <span class="wpcf7-form-control-wrap" data-name="file">
          <input size="40" class="wpcf7-form-control wpcf7-file" id="file" accept="audio/*,video/*,image/*" aria-invalid="false" type="file" name="file">
        </span>
        <!-- CF7のHTMLここまで -->
      </div>
    </div>
    <div class="bl_form_consent">
      <p class="bl_form_consent_desc">「<a class="bl_form_consent_desc_link" href="#">プライバシーポリシー</a>」をご確認いただき、同意のうえ送信してください。</p>
      <!-- CF7のHTMLここから -->
      <span class="wpcf7-form-control-wrap" data-name="acceptance">
        <span class="wpcf7-form-control wpcf7-acceptance">
          <span class="wpcf7-list-item">
            <label>
              <input type="checkbox" name="acceptance" value="1" id="consent" aria-invalid="false">
              <span class="wpcf7-list-item-label">同意する</span>
            </label>
          </span>
        </span>
      </span>
      <!-- CF7のHTMLここまで -->
    </div>
    <div class="bl_form_btn">
      <input class="bl_form_confirm" type="button" value="確認する" disabled>
    </div>
  </div>

  <!-- 確認画面 -->
  <div class="bl_formConfirm">
    <p class="bl_formConfirm_txt">以下の内容でよろしいですか?</p>
    <div class="bl_form_group">
      <p class="bl_form_label">お名前</p>
      <div class="bl_form_control">
        <p class="bl_confirm_name"></p>
      </div>
    </div>
    <div class="bl_form_group">
      <p class="bl_form_label">メールアドレス</p>
      <div class="bl_form_control">
        <p class="bl_confirm_email"></p>
      </div>
    </div>
    <div class="bl_form_group">
      <p class="bl_form_label">電話番号</p>
      <div class="bl_form_control">
        <p class="bl_confirm_tel"></p>
      </div>
    </div>
    <div class="bl_form_group">
      <p class="bl_form_label">お問い合わせ内容</p>
      <div class="bl_form_control">
        <p class="bl_confirm_message"></p>
      </div>
    </div>
    <div class="bl_form_group">
      <p class="bl_form_label">ラジオボタン</p>
      <div class="bl_form_control">
        <p class="bl_confirm_radio"></p>
      </div>
    </div>
    <div class="bl_form_group">
      <p class="bl_form_label">チェックボックス</p>
      <div class="bl_form_control">
        <p class="bl_confirm_checkbox"></p>
      </div>
    </div>
    <div class="bl_form_group">
      <p class="bl_form_label">セレクトボックス</p>
      <div class="bl_form_control">
        <p class="bl_confirm_select"></p>
      </div>
    </div>
    <div class="bl_form_group">
      <p class="bl_form_label">アップロードファイル</p>
      <div class="bl_form_control">
        <p class="bl_confirm_file"></p>
      </div>
    </div>
    <div class="bl_form_group">
      <p class="bl_form_label">プライバシーポリシー</p>
      <div class="bl_form_control">
        <p class="bl_confirm_consent">同意する</p>
      </div>
    </div>
    <div class="bl_form_btn">
      <input type="button" class="bl_form_back" value="戻る">
      <!-- CF7のHTMLここから -->
      <input class="wpcf7-form-control wpcf7-submit has-spinner bl_form_submit" type="submit" value="送信する">
      <!-- CF7のHTMLここまで -->
    </div>
  </div>
  <!-- Contact Form 7に貼り付ける部分ここまで↑ -->
</div>

入力画面と確認画面のHTMLは同一ページ内に記述します。

Contact Form 7の全入力フィールドにidを設定


[text* your_name id:name]
<p class="bl_confirm_name"></p>

Contact Form 7の全入力フィールドにidを設定してください。JavaScriptを使って入力内容を確認画面に反映できるようにします。設定したidは、確認画面の内容を表示する箇所を囲んでいる <p>class="bl_confirm_〇〇" の「〇〇」に記述してください。例えば、「お名前」のidname であれば、class="bl_confirm_name" のようにします。


<label class="bl_form_label" for="name">お名前</label>
[text* your_name id:name]

また、アクセシビリティの観点から、<label>for属性との関連付けにもidを使用します。

ラジオボタンとチェックボックスはグループ化


<fieldset>
  <legend class="bl_form_label">ラジオボタン</legend>
  <div class="bl_form_control">
    [radio radio id:radio class:bl_form_radio use_label_element default:1 "ラジオボタン1" "ラジオボタン2" "ラジオボタン3"]
  </div>
</fieldset>

<fieldset>
  <legend class="bl_form_label">チェックボックス</legend>
  <div class="bl_form_control">
    [checkbox checkbox id:checkbox class:bl_form_checkbox use_label_element "チェックボックス1" "チェックボックス2" "チェックボックス3"]
  </div>
</fieldset>

ラジオボタンとチェックボックスは、<fieldset><legend>でグループ化しています。
また、レイアウト調整のためのクラス名(class:bl_form_radioclass:bl_form_checkbox)を付与しています。

送信完了ページ


<div class="bl_formThanks">
  <h1 class="bl_formThanks_ttl">送信完了しました</h1>
  <p class="bl_formThanks_txt">メッセージは送信されました。お問い合わせいただきありがとうございました。</p>
</div>

送信完了ページは遷移させるので、それ用の固定ページを用意してください。

1-02. CSS


/* リセット */
*,
::before,
::after {
  box-sizing: border-box;
  border-style: solid;
  border-width: 0;
  min-inline-size: 0;
  margin: unset;
  padding: unset;
}

:where(button, input, textarea, optgroup, select) {
  appearance: none;
  background-color: transparent;
  border-radius: 0;
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  vertical-align: middle;
}

:where(textarea) {
  field-sizing: content;
  resize: block;
}

:where(button, [type="button"], [type="submit"], [type="reset"]) {
  text-align: center;
  user-select: none;
  touch-action: manipulation;
}

/* フォーカス時はオリジナルのアウトラインを適用 */
:where(button, input, textarea, select):focus-visible {
  outline: 2px solid #005FCC;
  outline-offset: -2px;
}

:where(button,
input[type=button],
input[type=submit],
input[type=reset])[disabled] {
  cursor: not-allowed;
}

/* レイアウト */
.ly_form {
  background-color: #F3F3F3;
  border: 2px solid #DDD;
  border-radius: 20px;
}

.bl_form,
.bl_formConfirm,
.bl_formThanks {
  padding-block: 50px;
  padding-inline: 30px;
}

.bl_form_group:not(:first-of-type) {
  margin-block-start: 1.5em;
}

.bl_form_group fieldset {
  display: contents;
}

.bl_form_control {
  margin-block-start: 0.5em;
}

.bl_formConfirm_txt + .bl_form_group {
  margin-block-start: 1.5em;
}

/* 項目名 */
.bl_form_label {
  align-items: center;
  display: inline-grid;
  gap: 0.6em;
  grid-template-columns: 1fr auto;
}

/* 必須ラベル */
.bl_form_required {
  background-color: red;
  color: #FFF;
  display: inline-block;
  font-weight: 700;
  padding-block: 0.1em;
  padding-inline: 0.2em;
}

/* 入力欄、セレクトボックス */
.bl_form :is(input[type=text], input[type=email], input[type=tel], textarea, select) {
  background-color: #FFF;
  border: 2px solid #DDD;
  padding-inline: 0.3em;
}

.bl_form :is(input[type=text], input[type=email], input[type=tel], textarea) {
  inline-size: 100%;
}

.bl_form :is(input[type=text], input[type=email], input[type=tel], textarea)::placeholder {
  color: #C5C5C5;
}

.bl_form textarea {
  min-block-size: 5lh;
}

/* ラジオボタン、チェックボックス */
.bl_form .wpcf7-list-item {
  margin: 0;
}

.bl_form_radio,
.bl_form_checkbox {
  display: inline-grid;
  gap: 0.5em 2em;
}

/* オリジナルのラジオボタンとチェックボックスを作成 */
.bl_form :is(input[type=radio], input[type=checkbox], input[type=checkbox]) {
  background-color: #FFF;
  block-size: 18px;
  border: 2px solid #DDD;
  inline-size: 18px;
  margin-block-end: 3px;
  position: relative;
}

.bl_form input[type=radio] {
  border-radius: 50%;
}

/* フォーカス時はlabelタグにアウトラインを適用 */
.bl_form label:has(:where(input[type=radio], input[type=checkbox]):focus-visible) {
  outline: 2px solid #005FCC;
  outline-offset: 2px;
}

/* チェック時のスタイルは擬似要素で再現 */
.bl_form :where(input[type=radio], input[type=checkbox]):checked::before {
  content: "";
  inset-block-start: 2px;
  inset-inline-start: 2px;
  position: absolute;
}

.bl_form :where(input[type=radio]):checked::before {
  background-color: #37952F;
  block-size: 10px;
  border-radius: 50%;
  inline-size: 10px;
}

.bl_form :where(input[type=checkbox]):checked::before {
  block-size: 6px;
  border-block-end: 2px solid #37952F;
  border-inline-start: 2px solid #37952F;
  inline-size: 10px;
  rotate: -50deg;
}

/* プライバシーポリシー */
.bl_form_consent {
  border: 2px solid #DDD;
  margin-block-start: 40px;
  padding-block: 1em;
  padding-inline: 1.3em;
  text-align: center;
}

.bl_form_consent_desc_link {
  color: #0000EE;
  text-decoration: underline;
}

/* バリデーションメッセージ */
/* .wpcf7-not-valid-tip{} */

/* 確認・戻る・送信ボタン */
.bl_form_btn {
  display: flex;
  gap: 2em;
  justify-content: center;
  margin-block-start: 40px;
}

/* 確認ボタン非活性時 */
.bl_form_confirm[disabled] {
  background-color: #CCC;
}

/* 確認・送信ボタン */
.bl_form_confirm,
.bl_form_submit {
  background-color: #37952F;
  color: #FFF;
  inline-size: min(100%, 10em);
  padding-block: 0.5em;
  padding-inline: 1em;
}

/* 戻るボタン */
.bl_form_back {
  text-decoration: underline;
}

/* 確認画面とメッセージ、スピナーを非表示 */
.bl_formConfirm,
.wpcf7-response-output,
.bl_formConfirm .wpcf7-spinner {
  display: none;
}

/* 送信完了画面 */
.bl_formThanks_ttl,
.bl_formThanks_txt {
  text-align: center;
}

.bl_formThanks_ttl {
  font-size: 24px;
  font-weight: 700;
}

.bl_formThanks_txt {
  margin-block-start: 1em;
}

@media (min-width: 768px) {
  .bl_form_group {
    align-items: start;
    display: grid;
    gap: 3%;
    grid-template-columns: 19% 1fr;
  }

  .bl_form_label {
    margin-block-start: 0.5em;
  }

  .bl_form_radio,
  .bl_form_checkbox {
    grid-auto-flow: column;
  }
}

見た目も再現できるようにすべてのCSSを掲載していますが、ご自身のリセットCSSの設定によっては多少違いが出てくると思います。

確認画面とメッセージ、スピナーを非表示


/* 確認画面とメッセージ、スピナーを非表示 */
.bl_formConfirm,
.wpcf7-response-output,
.bl_formConfirm .wpcf7-spinner {
  display: none;
}

確認画面の初期状態は非表示にしておき、JavaScriptで表示を切り替えます。
送信ボタンの下に表示されるメッセージと、右に表示されるスピナーも非表示にしています。

アウトライン


/* フォーカス時はオリジナルのアウトラインを適用 */
:where(button, input, textarea, select):focus-visible {
  outline: 2px solid #005FCC;
  outline-offset: -2px;
}

/* フォーカス時はlabelタグにアウトラインを適用 */
.bl_form label:has(:where(input[type=radio], input[type=checkbox]):focus-visible) {
  outline: 2px solid #005FCC;
  outline-offset: 2px;
}

ひと手間加えてオリジナルのアウトラインにしています。

1-03. JavaScript


window.addEventListener('DOMContentLoaded', () => {
  // --------------------
  // Contact Form 7:確認画面と送信完了ページを実装
  // --------------------
  const cF7 = document.getElementById('js_form'); // フォームを囲んでいるラッパー要素
  if (cF7) {
    // ----------
    // ラジオボタンの初期値を取得し、確認画面に反映させる
    // ----------
    let radio; // ラジオボタンの選択値を格納するための変数
    const radioButtons = document.querySelectorAll('[type="radio"]:checked');
    radioButtons.forEach(radioButton => {
      // ラジオボタンの選択値を取得
      radio = radioButton.value;
      // ラジオボタンの親要素からidを取得
      const id = radioButton.closest('[id]').id;
      // 取得したidをクラス名に追加し、確認画面の値を設定
      document.querySelector(`.bl_confirm_${id}`).textContent = radio;
    });

    // ----------
    // 入力フィールドの内容が変更された場合の処理
    // ----------
    const formInputs = document.querySelectorAll('.bl_form_group input, .bl_form_group select, .bl_form_group textarea');
    formInputs.forEach(input => {
      input.addEventListener('change', function () {
        let val = this.value; // 入力値を取得
        const type = this.getAttribute("type"); // 入力フィールドのタイプを取得
        // ラジオボタンの場合の処理
        if (type === "radio") {
          const radio = this.value; // 選択されたラジオボタンの値を取得
          const id = this.closest("[id]").id; // ラジオボタンの親要素のIDを取得
          document.querySelector(`.bl_confirm_${id}`).textContent = radio; // 対応する確認画面の要素に値をセット
        }
        // チェックボックスの場合の処理
        else if (type === "checkbox") {
          const checkboxes = document.querySelectorAll(`.bl_form_group input[type="checkbox"][name="${this.name}"]:checked`); // 選択されたチェックボックスを取得
          const check = Array.from(checkboxes).map(checkbox => checkbox.value).join('/'); // 選択されたチェックボックスの値を連結
          const id = this.closest("[id]").id; // チェックボックスの親要素のIDを取得
          document.querySelector(`.bl_confirm_${id}`).textContent = check; // 対応する確認画面の要素に値をセット
        }
        // セレクトボックスの場合の処理
        else if (this.tagName.toLowerCase() === 'select') {
          const select = Array.from(this.selectedOptions).map(option => option.value).join('/'); // 選択されたオプションの値を連結
          const id = this.id; // セレクトボックスのIDを取得
          document.querySelector(`.bl_confirm_${id}`).textContent = select; // 対応する確認画面の要素に値をセット
        }
        // その他の場合の処理(テキスト入力など)
        else {
          const id = this.id; // 入力フィールドのIDを取得
          document.querySelector(`.bl_confirm_${id}`).textContent = val; // 対応する確認画面の要素に値をセット
        }
      });
    });

    // ----------
    // 必須項目が変更された場合の処理
    // ----------
    const requiredInputs = document.querySelectorAll('[aria-required="true"]');
    const consentCheckbox = document.getElementById('consent');
    function checkFormValidity() {
      // フラグ
      let flag = true;
      // 必須項目をループで確認
      requiredElements.forEach(requiredElement => {
        if (requiredElement.value === "") {
          flag = false;
        }
      });
      // 承認確認の状態を確認
      if (consentCheckbox && !consentCheckbox.checked) {
        flag = false;
      }
      // フラグに基づいて確認ボタンを有効化/無効化
      confirmButton.disabled = !flag;
    }
    // 必須項目の入力イベントを監視
    requiredElements.forEach(requiredElement => {
      requiredElement.addEventListener('input', checkFormValidity);
    });
    // 承認確認の変更イベントを監視
    consentCheckbox.addEventListener('change', () => {
      document.querySelector('.bl_confirm_consent').textContent = consentCheckbox.checked ? '同意する' : '';
      checkFormValidity();
    });
    
    // ----------
    // 入力・確認画面の切り替えと表示位置の処理
    // ----------
    function toggleFormDisplay(showConfirm) {
      document.querySelector(".bl_form").style.display = showConfirm ? 'none' : 'revert';
      document.querySelector(".bl_formConfirm").style.display = showConfirm ? 'revert' : 'none';
      const headerHeight = document.getElementById('js_header').offsetHeight;
      const offsetTop = cF7.offsetTop - headerHeight;
      window.scrollTo(0, offsetTop);
    }

    // ----------
    // 確認ボタンをクリックした場合の処理
    // ----------
    const confirmButton = document.querySelector(".bl_form_confirm");
    if (confirmButton) {
      confirmButton.addEventListener('click', () => {
        toggleFormDisplay(true);
      });
    }

    // ----------
    // 戻るボタンをクリックした場合の処理
    // ----------
    const backButton = document.querySelector(".bl_form_back");
    if (backButton) {
      backButton.addEventListener('click', () => {
        toggleFormDisplay(false);
      });
    }
  }

  // ----------
  // 送信ボタンをクリックした場合の処理
  // ----------
  document.addEventListener('wpcf7mailsent', (event) => {
    location = 'https://○○/thanks/';
  }, false);

});

ラジオボタンの初期値を設定

// ----------
// ラジオボタンの初期値を取得し、確認画面に反映させる
// ----------
let radio; // ラジオボタンの選択値を格納するための変数
const radioButtons = document.querySelectorAll('[type="radio"]:checked');
radioButtons.forEach(radioButton => {
  // ラジオボタンの選択値を取得
  radio = radioButton.value;
  // ラジオボタンの親要素からidを取得
  const id = radioButton.closest('[id]').id;
  // 取得したidをクラス名に追加し、確認画面の値を設定
  document.querySelector(`.bl_confirm_${id}`).textContent = radio;
});

初期状態でチェックされているラジオボタンの値を取得して、確認画面に反映します。

入力内容変更時の処理

// ----------
// 入力フィールドの内容が変更された場合の処理
// ----------
const formInputs = document.querySelectorAll('.bl_form_group input, .bl_form_group select, .bl_form_group textarea');
formInputs.forEach(input => {
  input.addEventListener('change', function () {
    let val = this.value; // 入力値を取得
    const type = this.getAttribute("type"); // 入力フィールドのタイプを取得
    // ラジオボタンの場合の処理
    if (type === "radio") {
      const radio = this.value; // 選択されたラジオボタンの値を取得
      const id = this.closest("[id]").id; // ラジオボタンの親要素のIDを取得
      document.querySelector(`.bl_confirm_${id}`).textContent = radio; // 対応する確認画面の要素に値をセット
    }
    // チェックボックスの場合の処理
    else if (type === "checkbox") {
      const checkboxes = document.querySelectorAll(`.bl_form_group input[type="checkbox"][name="${this.name}"]:checked`); // 選択されたチェックボックスを取得
      const check = Array.from(checkboxes).map(checkbox => checkbox.value).join('/'); // 選択されたチェックボックスの値を連結
      const id = this.closest("[id]").id; // チェックボックスの親要素のIDを取得
      document.querySelector(`.bl_confirm_${id}`).textContent = check; // 対応する確認画面の要素に値をセット
    }
    // セレクトボックスの場合の処理
    else if (this.tagName.toLowerCase() === 'select') {
      const select = Array.from(this.selectedOptions).map(option => option.value).join('/'); // 選択されたオプションの値を連結
      const id = this.id; // セレクトボックスのIDを取得
      document.querySelector(`.bl_confirm_${id}`).textContent = select; // 対応する確認画面の要素に値をセット
    }
    // その他の場合の処理(テキスト入力など)
    else {
      const id = this.id; // 入力フィールドのIDを取得
      document.querySelector(`.bl_confirm_${id}`).textContent = val; // 対応する確認画面の要素に値をセット
    }
  });
});

承認確認を除く、入力フィールド(inputselecttextarea)の内容が変更されるたびに、その値を取得して確認画面に反映します。

必須項目変更時の処理

// ----------
// 必須項目が変更された場合の処理
// ----------
const requiredInputs = document.querySelectorAll('[aria-required="true"]');
const consentCheckbox = document.getElementById('consent');
function checkFormValidity() {
  // フラグ
  let flag = true;
  // 必須項目をループで確認
  requiredElements.forEach(requiredElement => {
    if (requiredElement.value === "") {
      flag = false;
    }
  });
  // 承認確認の状態を確認
  if (consentCheckbox && !consentCheckbox.checked) {
    flag = false;
  }
  // フラグに基づいて確認ボタンを有効化/無効化
  confirmButton.disabled = !flag;
}
// 必須項目の入力イベントを監視
requiredElements.forEach(requiredElement => {
  requiredElement.addEventListener('input', checkFormValidity);
});
// 承認確認の変更イベントを監視
consentCheckbox.addEventListener('change', () => {
  document.querySelector('.bl_confirm_consent').textContent = consentCheckbox.checked ? '同意する' : '';
  checkFormValidity();
});

必須項目の入力フィールドの内容が変更されるたびに、確認ボタンの有効化と無効化を切り替えています。必須項目として設定しているのは、aria-required="true"が付与されている「お名前」と「メールアドレス」です。承認確認には付与されないため、idで取得しています。

承認確認について


const consentCheckbox = document.getElementById('consent');

// 承認確認の状態を確認
if (consentCheckbox && !consentCheckbox.checked) {
  flag = false;
}

// 承認確認の変更イベントを監視
consentCheckbox.addEventListener('change', () => {
  document.querySelector('.bl_confirm_consent').textContent = consentCheckbox.checked ? '同意する' : '';
  checkFormValidity();
});

承認確認が不要の場合は、「必須項目が変更された場合の処理」にある上記のコードを削除してください。
「同意する」は確認画面に表示される文言になります。

入力・確認画面の表示切り替えと確認・戻るボタンの挙動について


// ----------
// 入力・確認画面の切り替えと表示位置の処理を行う関数
// ----------
function toggleFormDisplay(showConfirm) {
  document.querySelector(".bl_form").style.display = showConfirm ? 'none' : 'revert';
  document.querySelector(".bl_formConfirm").style.display = showConfirm ? 'revert' : 'none';
  const headerHeight = document.getElementById('js_header').offsetHeight;
  const offsetTop = cF7.offsetTop - headerHeight;
  window.scrollTo(0, offsetTop);
}

// ----------
// 確認ボタンをクリックした場合の処理
// ----------
const confirmButton = document.querySelector(".bl_form_confirm");
if (confirmButton) {
  confirmButton.addEventListener('click', () => {
    toggleFormDisplay(true);
  });
}

// ----------
// 戻るボタンをクリックした場合の処理
// ----------
const backButton = document.querySelector(".bl_form_back");
if (backButton) {
  backButton.addEventListener('click', () => {
    toggleFormDisplay(false);
  });
}

確認ボタンと戻るボタンのそれぞれのクリックによって、toggleFormDisplay関数の処理を分けています。例えば、toggleFormDisplayの引数(showConfirm)がtrueの場合、入力画面(.bl_form)を非表示にし、確認画面(.bl_formConfirm)を表示します。


const headerHeight = document.getElementById('js_header').offsetHeight;
const offsetTop = cF7.offsetTop - headerHeight;
window.scrollTo(0, offsetTop);

上記の部分は、固定ヘッダー(#js_header)の高さを取得して、フォームを囲んでいるラッパー要素(#js_form)と重ならないようにスクロール位置を調整しています。もし固定ヘッダーがない場合は、このコードを削除してください。

送信ボタンをクリックしたら送信完了ページへ遷移


// ----------
// 送信ボタンをクリックした場合の処理
// ----------
document.addEventListener('wpcf7mailsent', (event) => {
  location = 'https://○○/thanks/';
}, false);

遷移先となる固定ページのスラッグを、locationのところに記述してください。

まとめ

まとめ

プラグイン不要でContact Form 7の確認画面と送信完了ページを実装する方法について紹介しました。
きっかけとなる記事を書いてくれたしょーごさんに感謝です。

JavaScriptで入力画面の情報を確認画面に反映しつつ、画面切り替えと送信完了ページへの遷移まで行いました。
HTMLとCSSの入力画面のコードは、他のフォームコーディングにも応用できると思います。ぜひ参考にしてみてください。

フォームのデザインについては、もし前もってデザイナーと相談できる案件であれば、Contact Form 7の代わりに確認・完了画面が標準搭載されている「Snow Monkey Forms」の導入を検討してみてもいいかもしれません。

以上になります。

この記事が役に立ったら、応援してくれると嬉しいです! 投げ銭で応援する
 

人気記事Webサイトにフォントサイズ変更ボタンを実装する方法(jQuery使用)

人気記事【脱jQuery】スクロールしたら画面上部に追従メニューを表示する方法