【2026年版プラグイン不要】Contact Form 7に確認画面をつける方法|カスタムJSで軽量実装【コピペOK】

Contact Form 7(CF7)のフォームで、こんなことを実現したいと思ったことはありませんか?

ContactForm7の入力確認画面がほしい・・・

CF7にはデフォルトで確認画面がありません。

海外(特に英語圏)のUX標準では「送信 → 完了メッセージ」がシンプルで良しとされています。確認画面は「ユーザーに余計なステップを踏ませる」とむしろネガティブに捉えられることも多くて、CF7もその思想で作られています。

しかし日本では違います。
日本は「入力 → 確認 → 完了」の3ステップが ユーザーにとっての”安心感”として定着しています。

そのため、私も経験がありますが、こんな問題が起きることがあります。↓

  • 入力途中にEnterキーを押したら送信されてしまったユーザーからクレームが来た
  • 誤タップで送信されてしまったユーザーからクレームが来た
  • 「確認画面がないのは不親切では?」とクライアントに言われた


そう。現場ではトラブル防止のため、「確認画面が欲しい」というクライアントからの需要が非常に多いのです。

これまでは、苦肉の策でプラグインを使うなどで確認画面を表示させる方法がありましたが、配布元が長らく更新されていないものだったり、個人情報流出などのセキュリティの問題があったりしました。

そのため、この記事では、プラグインなし・jQuery + CSSだけで「ContactForm7に簡単な入力内容確認画面」を、モーダルウィンドウで実装する方法を解説します。

完成イメージ

送信ボタンを押すと、以下のような確認モーダルが表示されます。
(見た目はCSS側で変更可能です)

実現できる内容
  • プラグイン不要で、jQuery(WordPressに標準で入っているもの)で動きます
  • 入力した項目名と内容が一覧でモーダルウィンドウで表示され、「戻って修正」「送信する」が可能
  • 1つのサイトにある複数フォームにも対応
  • Conditional Fields Contact Form 7(条件分岐プラグイン)の分岐項目の表示にも対応
    (非表示フィールドは自動スキップ)
  • スマホ対応◎
できない点(要注意)
  • acceptanceの使用には非対応(送信不可がDOMの都合で外れちゃう挙動があるので、非対応としています…)
  • 複数フォームに対応してますが、フォームAは確認画面なし、フォームBは確認画面あり、のように切り分けはできません。すべて確認画面「あり」で運用されるのでご注意ください。

実装の流れ

  1. JSファイルを子テーマに設置する
  2. functions.php でJSを読み込む
  3. フォームIDとラベルを設定する
  4. CSSを追加する
  5. 動作確認

STEP 1:JSファイルを子テーマに設置する

以下のコードを cf7-confirm-modal.js というファイル名で保存してください。

保存場所は子テーマのディレクトリの中に js フォルダを作って入れるのがおすすめです。

/wp-content/themes/子テーマ名/js/cf7-confirm-modal.js

cf7-confirm-modal.js(全文)

/**
 * CF7 確認画面モーダル
 * 使い方:子テーマの functions.php で wp_enqueue_scripts にてこのJSを読み込む
 * 依存:jQuery(WPデフォルトで入ってるのでOK)
 */

(function ($) {

  const FORM_SELECTOR   = '.wpcf7-form';
  const SUBMIT_SELECTOR = '.wpcf7-submit';

  // ============================================================
  // 設定:フォームIDごとにラベルマップを定義
  //
  // キーはCF7のフォームID(数字)。
  // フォームのdiv.wpcf7にある data-wpcf7-id 属性か、
  // クラス名 wpcf7-f{ID}-... の数字部分で確認できます。
  //
  // ・IDが一致するフォーム → マップの項目を使用
  // ・IDが見つからない場合 → フォーム内のフィールドを自動収集(フォールバック)
  //
  // 同意チェックボックス(acceptanceタイプ)はどの場合も自動除外されます。
  // ============================================================
  const FIELD_LABELS_MAP = {
    // フォームIDをキーにして、項目名とラベルを定義する
    // 設定方法はSTEP 3を参照

    // フォームID: 「フォームA」の設定
    '123': {
      'your-name':    'お名前',
      'your-cname':   '法人名',
      'your-email':   'メールアドレス',
      'your-check[]':   'お問い合わせの種類',
      'your-message': 'お問い合わせ内容',
    },
    // フォームID:  「フォームB」の設定
    '456': {
      'your-name':    'お名前',
      'your-company':   '法人名',
      'your-email':   'メールアドレス',
      'your-check[]':  'お問い合わせの種類',
      'your-message': 'お問い合わせ内容',
    },
    // ↑ フォームIDと項目を案件に合わせて追加・変更してください
  };

  // ============================================================
  // ユーティリティ
  // ============================================================

  function getCf7FormId($form) {
    const $wrapper = $form.closest('.wpcf7');
    if (!$wrapper.length) return null;
    const dataId = $wrapper.attr('data-wpcf7-id');
    if (dataId) return dataId;
    const classes = $wrapper.attr('class') || '';
    const match = classes.match(/wpcf7-f(\d+)/);
    return match ? match[1] : null;
  }

  function isAcceptance($form, name) {
    return $form.find('[name="' + name + '"]').closest('.wpcf7-acceptance').length > 0;
  }

  function getFieldLabels($form, formId) {
    if (formId && FIELD_LABELS_MAP[formId]) {
      const labels = {};
      $.each(FIELD_LABELS_MAP[formId], function (name, label) {
        const baseName = name.replace(/\[\]$/, '');
        if (!isAcceptance($form, baseName)) {
          labels[name] = label;
        }
      });
      return labels;
    }
    // フォールバック:フォーム内のフィールドを自動収集
    const autoLabels = {};
    const seen = {};
    $form.find('[name]').each(function () {
      const name     = $(this).attr('name');
      const baseName = name ? name.replace(/\[\]$/, '') : '';
      const isAcc    = $(this).closest('.wpcf7-acceptance').length > 0;
      if (name && !name.startsWith('_') && !isAcc && !seen[baseName]) {
        seen[baseName]   = true;
        autoLabels[name] = baseName;
      }
    });
    return autoLabels;
  }

  // ============================================================
  // モーダルHTML生成
  // ============================================================
  function buildModal() {
    if ($('#cf7-confirm-modal').length) return;
    const html = [
      '<div id="cf7-confirm-modal" role="dialog" aria-modal="true" aria-labelledby="cf7-modal-title">',
        '<div id="cf7-confirm-overlay"></div>',
        '<div id="cf7-confirm-box">',
          '<h2 id="cf7-modal-title">入力内容のご確認</h2>',
          '<p class="cf7-confirm-lead">以下の内容で送信します。よろしければ「送信する」を押してください。</p>',
          '<dl id="cf7-confirm-table"></dl>',
          '<div class="cf7-confirm-buttons">',
            '<button type="button" id="cf7-back-btn">戻って修正する</button>',
            '<button type="button" id="cf7-send-btn">送信する</button>',
          '</div>',
        '</div>',
      '</div>',
    ].join('');
    $('body').append(html);
  }

  // ============================================================
  // フォームの入力値をモーダルに反映
  // ============================================================
  function populateModal($form) {
    const $table     = $('#cf7-confirm-table').empty();
    const formId     = getCf7FormId($form);
    const fieldLabels = getFieldLabels($form, formId);

    $.each(fieldLabels, function (name, label) {
      const $field = $form.find('[name="' + name + '"]');
      if (!$field.length) return;
      // Conditional Fieldsで非表示になっているフィールドはスキップ
      if ($field.closest('.wpcf7cf-hidden').length) return;

      let value = '';
      if ($field.is('select')) {
        value = $field.find('option:selected').text();
      } else if ($field.is(':checkbox')) {
        const checked = [];
        $form.find('[name="' + name + '"]:checked').each(function () {
          checked.push($(this).val());
        });
        value = checked.join('、') || '(未選択)';
      } else if ($field.is(':radio')) {
        value = $form.find('[name="' + name + '"]:checked').val() || '(未選択)';
      } else {
        value = $field.val() || '(未入力)';
      }

      // 改行をbrに変換(テキストエリア対応)
      value = $('<div>').text(value).html().replace(/\n/g, '<br>');

      $table.append(
        '<div class="cf7-confirm-row">' +
          '<dt>' + label + '</dt>' +
          '<dd>' + value + '</dd>' +
        '</div>'
      );
    });
  }

  // ============================================================
  // モーダル表示・非表示
  // ============================================================
  function showModal() {
    $('#cf7-confirm-modal').addClass('is-visible');
    $('body').addClass('cf7-modal-open');
    $('#cf7-confirm-box').scrollTop(0);
    $('#cf7-modal-title').focus();
  }

  function hideModal() {
    $('#cf7-confirm-modal').removeClass('is-visible');
    $('body').removeClass('cf7-modal-open');
    $(SUBMIT_SELECTOR).focus();
  }

  // ============================================================
  // 実際の送信
  // ============================================================
  function submitForm($form) {
    $form.data('cf7-confirmed', true);
    hideModal();
    $form.find(SUBMIT_SELECTOR).trigger('click');
  }

  // ============================================================
  // 初期化
  // ============================================================
  $(document).ready(function () {
    buildModal();

    function bindSubmitHandler($form) {
      $form.find(SUBMIT_SELECTOR).off('click.cf7modal').on('click.cf7modal', function (e) {
        if ($form.data('cf7-confirmed')) {
          $form.data('cf7-confirmed', false);
          return;
        }
        e.preventDefault();
        populateModal($form);
        showModal();
        $('#cf7-send-btn').data('form', $form);
      });
    }

    $(FORM_SELECTOR).each(function () {
      bindSubmitHandler($(this));
    });

    $(document).on('click', '#cf7-send-btn', function () {
      submitForm($(this).data('form'));
    });

    $(document).on('click', '#cf7-back-btn, #cf7-confirm-overlay', function () {
      hideModal();
    });

    $(document).on('keydown', function (e) {
      if (e.key === 'Escape' && $('#cf7-confirm-modal').hasClass('is-visible')) {
        hideModal();
      }
    });
  });

})(jQuery);

STEP 2:functions.php でJSを読み込む

子テーマの functions.php に以下を追加してください。

add_action( 'wp_enqueue_scripts', function () {
    wp_enqueue_script(
        'cf7-confirm-modal',                                          // ハンドル名(任意)
        get_stylesheet_directory_uri() . '/js/cf7-confirm-modal.js', // ファイルパス
        array( 'jquery' ),                                            // jQueryに依存
        '1.0.0',                                                      // バージョン
        true                                                          // フッターで読み込む
    );
} );
ポイント

第3引数の array('jquery') を必ず書いてください。
これによりjQueryより後に読み込まれるようになります。省略するとエラーになります。

STEP 3:フォームIDとラベルを設定する

ここが一番大事なカスタマイズ箇所です。
JSファイルの FIELD_LABELS_MAP を、自分のフォームの内容に書き換えます。

必要な情報は2つです。

  • CF7のフォームID(数字)
  • 各フィールドのname属性

順番に確認方法を説明します。

まずは、
フォームIDの確認方法

新しいCF7(5.x以降)の場合:data-wpcf7-id 属性を確認するだけです。
フォームを設置しているページの「ソース」を開き、「data-wpcf7-id=」という文字列でソース検索するとそのフォームのID(数字)がわかります。

古いCF7の場合は、クラス名から確認できます。
クラス名の wpcf7-f〇〇〇 の数字部分がIDです。↓

<div class=”wpcf7 wpcf7-f123-p12-o1″>

つぎに、
フィールドのname属性の確認方法

コンタクトフォーム側の、入力項目に「your-name」「your-email」などname項目をつけていますよね?

これがname属性にあたります。
CF7が出力されているフォームのソースからもname=”◯◯”で同様に確認できます。

そして
いざ設定!FIELD_LABELS_MAP の書き方

確認できたフォームIDとname属性を使って、以下の形式で書きます。

const FIELD_LABELS_MAP = {

  // フォームIDを文字列で書く(数字でもOKだが文字列推奨)
  '123': {
    // 'name属性': '確認モーダルに表示したいラベル名'
    'your-name':    'お名前',
    'your-email':   'メールアドレス',
    'your-message': 'お問い合わせ内容',

    // チェックボックスは [] ごと書く
    'your-check[]': 'お問い合わせの種類',
  },

  // フォームが複数ある場合はカンマで区切って追加
  '456': {
    'your-name':    'お名前',
    'your-email':   'メールアドレス',
    'your-budget':  'ご予算',
    'your-message': '依頼内容',
  },

};
チェックボックスのみ[]をつけてください!

チェックボックスのみ、name属性の終わりに [] という括弧をつける必要があります。

‘your-check[]’: ‘お問い合わせの種類’,

↑このように、FIELD_LABELS_MAP のキーにも [] という括弧を含めて書かないと取得できませんのでご注意ください!

STEP 4:CSSを追加する

WordPress管理画面 → 外観 → カスタマイズ → 追加CSS に以下を貼り付けてください。
サイトに合わせてご自身でカスタマイズされてもOKです!

/* =====================
   CF7 確認モーダル
===================== */
/* モーダル本体(非表示時) */
#cf7-confirm-modal {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 9999;
}
/* .is-visible クラスが付いたとき表示 */
#cf7-confirm-modal.is-visible {
  display: block;
}
/* 背景オーバーレイ(半透明の黒) */
#cf7-confirm-overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
}
/* モーダルボックス本体 */
#cf7-confirm-box {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: #fff;
  border-radius: 8px;
  padding: 32px 28px;
  width: 90%;
  max-width: 560px;
  max-height: 80vh;        /* 画面高さの80%を超えたらスクロール */
  overflow-y: auto;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);
}
/* タイトル */
#cf7-confirm-box h2 {
  font-size: 18px;
  margin: 0 0 8px;
  color: #333;
}
/* リード文 */
.cf7-confirm-lead {
  font-size: 14px;
  color: #666;
  margin: 0 0 20px;
  line-height: 1.7;
}
/* 入力内容テーブル(dl要素) */
#cf7-confirm-table {
  margin: 0 0 24px;
  padding: 0;
}
/* 1行分(項目名 + 入力値) */
.cf7-confirm-row {
  display: grid;
  grid-template-columns: 140px 1fr;  /* 左:項目名 / 右:入力値 */
  gap: 8px 16px;
  padding: 12px 0;
  border-bottom: 1px solid #eee;
  font-size: 14px;
  line-height: 1.6;
}
.cf7-confirm-row:first-child {
  border-top: 1px solid #eee;
}
/* 項目名 */
.cf7-confirm-row dt {
  font-weight: bold;
  color: #555;
  word-break: break-all;
}
/* 入力値 */
.cf7-confirm-row dd {
  margin: 0;
  color: #333;
  word-break: break-all;
}
/* ボタンエリア */
.cf7-confirm-buttons {
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
}
/* 「戻って修正する」ボタン */
#cf7-back-btn {
  padding: 10px 24px;
  background: #f0f0f0;
  color: #555;
  border: none;
  border-radius: 4px;
  font-size: 14px;
  cursor: pointer;
  transition: background 0.2s;
}
#cf7-back-btn:hover {
  background: #ddd;
}
/* 「送信する」ボタン */
#cf7-send-btn {
  padding: 10px 24px;
  background: #4a90e2;
  color: #fff;
  border: none;
  border-radius: 4px;
  font-size: 14px;
  cursor: pointer;
  transition: background 0.2s;
}
#cf7-send-btn:hover {
  background: #357abd;
}
/* モーダル表示中はページ本体のスクロールを禁止 */
body.cf7-modal-open {
  overflow: hidden;
}
/* ===============
   スマホ対応
=============== */
@media (max-width: 480px) {
  #cf7-confirm-box {
    padding: 24px 16px;
  }
  /* スマホでは項目名と入力値を縦並びに */
  .cf7-confirm-row {
    grid-template-columns: 1fr;
    gap: 4px;
  }
}

STEP 5:動作確認

以下の順番で動作確認してください。

  • フォームに入力して送信ボタンを押す → モーダルが表示される
  • モーダルに入力内容が正しく表示されている
  • 「戻って修正する」でフォームに戻れる
  • 背景クリックでモーダルが閉じる
  • Escキーでモーダルが閉じる
  • 「送信する」でメールが届く(テスト送信)
設定なしでもとりあえず動くかどうかも確認OK

フォームIDが見つからない場合・とりあえず動作確認したい場合: FIELD_LABELS_MAP に一致するIDがない場合は、フォーム内のすべての入力フィールドを自動収集して表示します(フォールバック動作)。 ラベルはname属性がそのまま表示されるので見た目は粗いですが、動作確認には使えます。

よくあるトラブルと対処

モーダルが表示されない

ブラウザの開発者ツール(F12)→ コンソールタブを開いてエラーを確認してください。

$ is not defined と出ている場合は、jQueryが読み込まれていないかJSの読み込み順の問題です。
functions.phparray('jquery') の記述を確認してください。

入力内容が表示されない・項目が足りない

FIELD_LABELS_MAP のキー(フォームID)が実際のIDと一致していない可能性があります。
開発者ツールで data-wpcf7-id の値を再確認してください。

一致していない場合はフォールバック動作になり、ラベルがname属性のまま表示されます。

チェックボックスが表示されない

FIELD_LABELS_MAP のキーに [] を含めているか確認してください。

// ❌ 表示されない
'your-check': 'お問い合わせの種類',
// ✅ 正しい書き方
'your-check[]': 'お問い合わせの種類',

モーダルがヘッダーや他の要素の裏に隠れる

CSSの z-index: 999999999 に上げてみてください。

#cf7-confirm-modal {
  z-index: 99999; /* 数字を大きくする */
}

まとめ

この記事では、CF7の送信前に入力内容一覧を確認モーダルで表示する方法を紹介しました。

  • JSとCSSの2点で完結、プラグイン追加なし
  • テキスト・チェックボックス・セレクト・ラジオボタンすべて対応
  • 複数フォームも FIELD_LABELS_MAP にIDを追加するだけで対応できる
  • フォームの項目が変わったときも設定を更新するだけでOK

「フォームIDとname属性を調べて FIELD_LABELS_MAP に書く」
という作業さえできれば、あとはコピペで動きます。

非常に簡易的なものですが、軽量に動きます。
ぜひ試してみてくださいね。

最終更新:2026年3月。
WordPressのアップデートやCF7のアップデートで動作しなくなる可能性があります。気になることやお困りのことがありましたら、コメントでお寄せください。

この記事を書いた人

はなわ

パリスタデザイン事務所のWebデザイナー・フロントエンドエンジニア。
WordPress構築・カスタマイズを中心に、CMS設計・構築や情報設計を得意としています。
AIやWeb技術、PC/ガジェットを活用しながら、「無理なく続く仕組みづくり」や実務に役立つ知見を発信しています。

お仕事のご依頼はこちら

パリスタデザイン事務所では、WordPress構築・カスタマイズを中心に、Web制作に関するご相談を承っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA