【プラグイン不要】Contact Form 7で確認画面を実装する方法【コピペOK】
はじめに
WordPressの定番お問い合わせフォームプラグイン「Contact Form 7」。とても便利ですが、確認画面がないのが悩みどころですよね。
以前は「Contact Form 7 Multi-Step Forms」などのプラグインで対応できましたが、プラグインの相性問題やメンテナンス停止のリスクもあります。
この記事では、プラグインを使わずにJavaScriptとCSSだけで確認画面を実装する方法を、コピペで使えるコードとともに解説します。
この記事でできること
- Contact Form 7 のフォームに「確認画面」を追加できる
- 入力内容のバリデーション(必須チェック・メールアドレス一致チェック)ができる
- 確認画面 → 入力画面の行き来ができる
- プラグインなしで完結する
前提条件
- WordPress がインストール済みであること
- Contact Form 7 がインストール・有効化済みであること
- テーマのJavaScriptファイルを編集できること(子テーマ推奨)
完成イメージ
実装後のフォームは、以下の3ステップで動作します。
- 入力画面 — ユーザーが各項目を入力する
- 確認画面 — 入力内容を一覧表示して確認してもらう
- 送信完了 — Contact Form 7 の送信処理が実行され、サンクスページへ遷移する
確認ボタンは、すべての必須項目が入力されるまで無効化(disabled)されます。メールアドレスの一致チェックもリアルタイムで行います。
実装手順
Step 1:Contact Form 7 のフォームテンプレートを設定する
Contact Form 7 の管理画面で、フォームテンプレートを以下の内容に書き換えます。
ポイントは、入力画面(.c-form)と確認画面(.c-form__confirm)を1つのフォーム内に並べて配置することです。確認画面は JavaScript で表示/非表示を切り替えます。
<!-- form - フォーム画面 -->
<div class="c-form">
<div class="c-form__header">
<p>サービスや採用に関するご質問やご相談は、下記の項目に内容を入力いただき、
「確認する」ボタンをクリックしてください。<br>
内容を確認後、弊社担当よりメールにてご連絡いたします。</p>
</div>
<div class="c-form__body">
<div class="c-form__item">
<label>
<span class="c-form__label">
<span class="c-form__label-text">会社名</span>
<span class="c-form__required-label">必須</span>
</span>
<span class="c-form__control">
[text* company-name placeholder "株式会社〇〇"]
</span>
</label>
</div>
<div class="c-form__item">
<label>
<span class="c-form__label">
<span class="c-form__label-text">お名前</span>
<span class="c-form__required-label">必須</span>
</span>
<span class="c-form__control">
[text* your-name autocomplete:name placeholder "山田 太郎"]
</span>
</label>
</div>
<div class="c-form__item">
<label>
<span class="c-form__label">
<span class="c-form__label-text">メールアドレス</span>
<span class="c-form__required-label">必須</span>
</span>
<span class="c-form__control">
[email* your-email autocomplete:email placeholder "sample@example.com"]
</span>
</label>
</div>
<div class="c-form__item">
<label>
<span class="c-form__label">
<span class="c-form__label-text">確認用メールアドレス</span>
<span class="c-form__required-label">必須</span>
</span>
<span class="c-form__control">
[email* confirm-email autocomplete:email placeholder "sample@example.com"]
</span>
</label>
</div>
<div class="c-form__item">
<label>
<span class="c-form__label">
<span class="c-form__label-text">電話番号</span>
<span class="c-form__required-label">必須</span>
</span>
<span class="c-form__control">
[tel* tel autocomplete:tel placeholder "03-1234-5678"]
</span>
</label>
</div>
<div class="c-form__item">
<label>
<span class="c-form__label">
<span class="c-form__label-text">お問い合わせ種別</span>
<span class="c-form__required-label">必須</span>
</span>
<span class="c-form__control">
[select* category first_as_label
"選択してください"
"サービスについて"
"採用について"
"その他"]
</span>
</label>
</div>
<div class="c-form__item">
<label>
<span class="c-form__label">
<span class="c-form__label-text">お問い合わせ内容</span>
<span class="c-form__required-label">必須</span>
</span>
<span class="c-form__control">
[textarea* your-message placeholder "お問い合わせ内容をご入力ください。"]
</span>
</label>
</div>
</div>
<div class="c-form__footer">
<div class="c-form__btns">
<div class="c-form__btn-wrap">
<input type="button" class="c-form__btn" id="confirm_button"
value="確認する" disabled>
</div>
</div>
</div>
</div>
<!-- /form -->
<!-- confirm - 確認画面 -->
<div class="c-form__confirm">
<div class="c-form__header">
<p>以下の内容でお間違いがないかご確認ください。<br>
内容に問題がなければ「送信」ボタンを押してください。</p>
</div>
<div class="c-form__confirm-body">
<dl class="c-datalist">
<div class="c-form__confirm-item c-datalist__row"
data-name="company-name">
<dt><p>会社名</p></dt>
<dd></dd>
</div>
<div class="c-form__confirm-item c-datalist__row"
data-name="your-name">
<dt><p>お名前</p></dt>
<dd></dd>
</div>
<div class="c-form__confirm-item c-datalist__row"
data-name="your-email">
<dt><p>メールアドレス</p></dt>
<dd></dd>
</div>
<div class="c-form__confirm-item c-datalist__row"
data-name="tel">
<dt><p>電話番号</p></dt>
<dd></dd>
</div>
<div class="c-form__confirm-item c-datalist__row"
data-name="category">
<dt><p>お問い合わせ種別</p></dt>
<dd></dd>
</div>
<div class="c-form__confirm-item c-datalist__row"
data-name="your-message">
<dt><p>お問い合わせ内容</p></dt>
<dd></dd>
</div>
</dl>
</div>
<div class="c-form__footer">
<div class="c-form__btns">
<div class="c-form__btn-wrap">
<input type="button" class="c-form__btn c-form__btn--back"
id="back_button" value="入力画面に戻る">
</div>
<div class="c-form__btn-wrap">
[submit "送信"]
</div>
</div>
</div>
</div>
<!-- /confirm -->フォームテンプレートのポイント:
[text* ...]のように*をつけると Contact Form 7 側で必須項目になります- 確認画面の
data-name属性は、入力フィールドのname属性と一致させてください - 確認ボタンは
type="button"です(type="submit"ではありません)。送信ボタンは確認画面側にだけ配置します first_as_labelを使うと、セレクトボックスの最初の項目がプレースホルダーとして扱われます
Step 2:JavaScript を追加する
以下の JavaScript をテーマの JS ファイルに追加します。jQuery に依存していますので、WordPress に標準で含まれている jQuery を利用します。
/**
* Contact Form 7 確認画面つきフォーム
* jQuery 不要・クラス構文不要のプレーン JavaScript
*/
(function () {
'use strict';
// ============================================
// 設定値(環境に合わせて変更してください)
// ============================================
var THANKS_URL = '/contact/thanks/'; // 送信完了後の遷移先
// ============================================
// フォームデータの保持用
// ============================================
var formData = {};
// ============================================
// 初期化
// ============================================
function init() {
var confirmScreen = document.querySelector('.c-form__confirm');
var confirmBtn = document.getElementById('confirm_button');
// 確認画面を非表示にする
if (confirmScreen) confirmScreen.style.display = 'none';
// 確認ボタンを無効化
if (confirmBtn) confirmBtn.disabled = true;
// イベントの登録
bindEvents();
// テキストエリアの自動リサイズ
setupTextareaAutoResize();
// セレクトボックスの初期色設定
initializeSelectElements();
}
// ============================================
// イベント登録
// ============================================
function bindEvents() {
var formBody = document.querySelector('.c-form__body');
if (!formBody) return;
// 入力・変更を監視(イベント委譲で一括管理)
formBody.addEventListener('input', onFieldChange);
formBody.addEventListener('change', function (e) {
onFieldChange();
// セレクトボックスは色の切り替えも行う
if (e.target.tagName === 'SELECT') {
handleSelectChange(e.target);
}
});
// 確認ボタン → 確認画面を表示
var confirmBtn = document.getElementById('confirm_button');
if (confirmBtn) {
confirmBtn.addEventListener('click', showConfirmScreen);
}
// 戻るボタン → 入力画面に戻る
var backBtn = document.getElementById('back_button');
if (backBtn) {
backBtn.addEventListener('click', showInputScreen);
}
// Contact Form 7 の送信完了 → サンクスページへ遷移
document.addEventListener('wpcf7mailsent', function () {
location.href = THANKS_URL;
});
}
// ============================================
// 入力値が変わるたびに呼ばれる共通処理
// ============================================
function onFieldChange() {
collectFormData();
updateConfirmData();
updateConfirmButton();
}
// ============================================
// フォームの全入力値を収集する
// ============================================
function collectFormData() {
formData = {};
var body = document.querySelector('.c-form__body');
if (!body) return;
// テキスト・メール・電話番号
var inputs = body.querySelectorAll(
'input[type="text"], input[type="email"], input[type="tel"]'
);
for (var i = 0; i < inputs.length; i++) {
if (inputs[i].name) formData[inputs[i].name] = inputs[i].value;
}
// セレクトボックス
var selects = body.querySelectorAll('select');
for (var i = 0; i < selects.length; i++) {
if (selects[i].name) formData[selects[i].name] = selects[i].value;
}
// テキストエリア
var textareas = body.querySelectorAll('textarea');
for (var i = 0; i < textareas.length; i++) {
if (textareas[i].name) formData[textareas[i].name] = textareas[i].value;
}
}
// ============================================
// 確認画面の表示内容を更新する
// ============================================
function updateConfirmData() {
var items = document.querySelectorAll('.c-form__confirm-item');
for (var i = 0; i < items.length; i++) {
var name = items[i].getAttribute('data-name');
if (name && formData[name] !== undefined) {
var dd = items[i].querySelector('dd');
if (dd) dd.textContent = formData[name] || '';
}
}
}
// ============================================
// 確認ボタンの有効/無効を切り替える
// ============================================
function updateConfirmButton() {
var body = document.querySelector('.c-form__body');
if (!body) return;
// CF7 が自動付与する aria-required="true" を利用して必須項目を取得
var requiredFields = body.querySelectorAll(
'input[aria-required="true"], select[aria-required="true"], textarea[aria-required="true"]'
);
// すべての必須項目が埋まっているかチェック
var allFilled = true;
for (var i = 0; i < requiredFields.length; i++) {
var val = requiredFields[i].value;
if (!val || val.trim() === '') {
allFilled = false;
break;
}
}
// メールアドレスの一致チェック
var email = formData['your-email'] || '';
var confirmEmail = formData['confirm-email'] || '';
var emailsMatch = true;
if (email && confirmEmail) {
emailsMatch = email === confirmEmail;
}
showEmailError(emailsMatch);
// ボタンの有効/無効を切り替え
var btn = document.getElementById('confirm_button');
if (btn) btn.disabled = !(allFilled && emailsMatch);
}
// ============================================
// メールアドレス不一致エラーの表示/非表示
// ============================================
function showEmailError(emailsMatch) {
var confirmField = document.querySelector('[name="confirm-email"]');
if (!confirmField) return;
// 既存のエラーメッセージがあれば削除
var parent = confirmField.parentElement;
if (parent) {
var existing = parent.querySelector('.custom-error');
if (existing) existing.remove();
}
// 両方入力済みで不一致の場合だけエラーを表示
if (formData['your-email'] && formData['confirm-email'] && !emailsMatch) {
var error = document.createElement('span');
error.className = 'custom-error';
error.textContent = 'メールアドレスが一致しません';
error.style.cssText =
'color: red; font-size: 12px; display: block; margin-top: 5px;';
confirmField.parentNode.insertBefore(error, confirmField.nextSibling);
}
}
// ============================================
// テキストエリアの高さ自動調整
// ============================================
function setupTextareaAutoResize() {
var textareas = document.querySelectorAll('.c-form__body textarea');
for (var i = 0; i < textareas.length; i++) {
(function (textarea) {
var initialHeight = textarea.clientHeight;
textarea.addEventListener('input', function () {
textarea.style.height = initialHeight + 'px';
textarea.style.height = textarea.scrollHeight + 'px';
});
})(textareas[i]);
}
}
// ============================================
// セレクトボックスの初期設定
// ============================================
function initializeSelectElements() {
var selects = document.querySelectorAll('.c-form__body select');
for (var i = 0; i < selects.length; i++) {
handleSelectChange(selects[i]);
}
}
// ============================================
// セレクトボックスの値に応じてクラスを切り替え
// (未選択時はグレー、選択時は通常色にする)
// ============================================
function handleSelectChange(selectElement) {
if (selectElement.value && selectElement.value !== '') {
selectElement.classList.add('has-value');
} else {
selectElement.classList.remove('has-value');
}
}
// ============================================
// 確認画面を表示する
// ============================================
function showConfirmScreen() {
var inputScreen = document.querySelector('.c-form');
var confirmScreen = document.querySelector('.c-form__confirm');
if (inputScreen) inputScreen.style.display = 'none';
if (confirmScreen) confirmScreen.style.display = 'block';
window.scrollTo({ top: 0, behavior: 'smooth' });
}
// ============================================
// 入力画面に戻る
// ============================================
function showInputScreen() {
var confirmScreen = document.querySelector('.c-form__confirm');
var inputScreen = document.querySelector('.c-form');
if (confirmScreen) confirmScreen.style.display = 'none';
if (inputScreen) inputScreen.style.display = 'block';
window.scrollTo({ top: 0, behavior: 'smooth' });
}
// ============================================
// DOM 読み込み完了後に初期化を実行
// ============================================
document.addEventListener('DOMContentLoaded', init);
})();JavaScriptのポイント:
- jQuery 不要です。ブラウザ標準の
document.querySelectorなどだけで動作します - クラス構文(
class)も使っていません。関数の集まりとして書いているので、初心者の方でも各処理が追いやすい構成です - 即時実行関数
(function() { ... })()で囲むことで、グローバル変数の汚染を防いでいます - Contact Form 7 は必須項目に
aria-required="true"を自動で付与するので、これを利用してバリデーションしています wpcf7mailsentは Contact Form 7 が送信成功時に発火するカスタムイベントです。サンクスページの URL は冒頭のTHANKS_URLで変更できます
Step 3:CSS を追加する
最後に、フォームの見た目を整える CSS を追加します。テーマの style.css や追加 CSS に記述してください。
/* =============================================
Contact Form - 基本レイアウト
============================================= */
/* フォーム全体 */
.c-form,
.c-form__confirm {
max-width: 720px;
margin: 0 auto;
padding: 40px 20px;
}
/* ヘッダー */
.c-form__header p {
font-size: 14px;
line-height: 1.8;
color: #555;
margin-bottom: 32px;
}
/* =============================================
入力画面
============================================= */
/* 各入力項目 */
.c-form__item {
margin-bottom: 24px;
}
.c-form__item label {
display: block;
}
/* ラベル */
.c-form__label {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 8px;
}
.c-form__label-text {
font-size: 14px;
font-weight: bold;
color: #333;
}
/* 必須ラベル */
.c-form__required-label {
display: inline-block;
background: #e74c3c;
color: #fff;
font-size: 11px;
padding: 2px 8px;
border-radius: 3px;
line-height: 1.4;
}
/* 入力コントロール */
.c-form__control input[type="text"],
.c-form__control input[type="email"],
.c-form__control input[type="tel"],
.c-form__control select,
.c-form__control textarea {
width: 100%;
padding: 12px 16px;
border: 1px solid #ccc;
border-radius: 6px;
font-size: 16px;
line-height: 1.5;
background: #fff;
transition: border-color 0.2s;
box-sizing: border-box;
}
.c-form__control input:focus,
.c-form__control select:focus,
.c-form__control textarea:focus {
outline: none;
border-color: #3498db;
box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.15);
}
/* セレクトボックス - 未選択時のスタイル */
.c-form__control select {
color: #999;
}
.c-form__control select.has-value {
color: #333;
}
/* テキストエリア */
.c-form__control textarea {
min-height: 150px;
resize: vertical;
}
/* =============================================
ボタン
============================================= */
.c-form__btns {
display: flex;
justify-content: center;
gap: 16px;
margin-top: 40px;
}
.c-form__btn {
display: inline-block;
padding: 14px 48px;
font-size: 16px;
font-weight: bold;
color: #fff;
background: #3498db;
border: none;
border-radius: 6px;
cursor: pointer;
transition: background 0.2s, opacity 0.2s;
}
.c-form__btn:hover {
background: #2980b9;
}
.c-form__btn:disabled {
background: #ccc;
cursor: not-allowed;
opacity: 0.7;
}
/* 戻るボタン */
.c-form__btn--back {
background: #95a5a6;
}
.c-form__btn--back:hover {
background: #7f8c8d;
}
/* CF7の送信ボタン */
.c-form__confirm .wpcf7-submit {
display: inline-block;
padding: 14px 48px;
font-size: 16px;
font-weight: bold;
color: #fff;
background: #e67e22;
border: none;
border-radius: 6px;
cursor: pointer;
transition: background 0.2s;
}
.c-form__confirm .wpcf7-submit:hover {
background: #d35400;
}
/* =============================================
確認画面
============================================= */
.c-form__confirm {
display: none; /* 初期状態は非表示 */
}
/* 確認データリスト */
.c-datalist__row {
display: flex;
border-bottom: 1px solid #eee;
padding: 16px 0;
}
.c-datalist__row dt {
width: 200px;
flex-shrink: 0;
font-weight: bold;
font-size: 14px;
color: #333;
}
.c-datalist__row dd {
flex: 1;
font-size: 14px;
color: #555;
margin: 0;
word-break: break-all;
}
/* エラーメッセージ */
.custom-error {
color: #e74c3c;
font-size: 12px;
display: block;
margin-top: 5px;
}
/* =============================================
レスポンシブ
============================================= */
@media (max-width: 768px) {
.c-datalist__row {
flex-direction: column;
gap: 4px;
}
.c-datalist__row dt {
width: 100%;
}
.c-form__btns {
flex-direction: column;
align-items: center;
}
.c-form__btn,
.c-form__confirm .wpcf7-submit {
width: 100%;
text-align: center;
}
}Step 4:JavaScript ファイルの読み込み
テーマの functions.php に以下を追加して、JavaScript ファイルを読み込みます。
function enqueue_contact_form_confirm_script() {
// お問い合わせページでのみ読み込む(スラッグは環境に合わせて変更)
if (is_page('contact')) {
wp_enqueue_script(
'contact-form-confirm',
get_stylesheet_directory_uri() . '/assets/js/contact-form-confirm.js',
array(), // jQuery不要
'1.0.0',
true // フッターで読み込み
);
}
}
add_action('wp_enqueue_scripts', 'enqueue_contact_form_confirm_script');JS ファイルは 子テーマ/assets/js/contact-form-confirm.js として保存してください。パスは環境に合わせて調整してください。
仕組みの解説
この実装は、とてもシンプルな原理で動いています。
Contact Form 7 の <form> タグの中に「入力画面」と「確認画面」の2つの <div> を並べて配置し、JavaScript で display: none / block を切り替えているだけです。確認画面の送信ボタン([submit "送信"])はあくまで Contact Form 7 のショートコードなので、CF7 のバリデーションと送信処理はそのまま動作します。
データの流れを整理すると以下のようになります。
- ユーザーが入力 →
input/changeイベントが発火 - JavaScript が
formDataオブジェクトに全項目の値を収集 - 必須項目の入力チェック+メールアドレス一致チェックを実行
- すべてOKなら確認ボタンを有効化
- 確認ボタンを押すと、
formDataの内容を確認画面の<dd>に表示 - 送信ボタンを押すと、CF7 が通常どおりフォームを送信
入力値は <input> 要素にそのまま残っているため、確認画面と入力画面を何度行き来してもデータが消えることはありません。
カスタマイズのヒント
フォーム項目を追加・変更したい場合
入力画面と確認画面の両方を編集する必要があります。
- 入力画面(
.c-form__body)に新しいc-form__itemを追加する - 確認画面(
.c-form__confirm-body)に、同じdata-nameを持つc-form__confirm-itemを追加する
data-name の値をフォームフィールドの name 属性と一致させれば、JavaScript 側の変更は不要です。
サンクスページの遷移先を変更したい場合
JavaScript 冒頭の設定値 THANKS_URL を変更してください。
var THANKS_URL = '/your-thanks-page/'; // ← ここを変更個人情報保護方針への同意チェックボックスを追加したい場合
入力画面のフッター部分(確認ボタンの上)にチェックボックスを追加し、JavaScript の updateConfirmButton メソッド内でチェック状態を条件に加えてください。
<!-- フォームテンプレートに追加 -->
<div class="c-form__item">
[acceptance accept-privacy-policy]
<a href="/privacy-policy/" target="_blank">個人情報保護方針</a>に同意する
[/acceptance]
</div>よくあるトラブルと対処法
Q. 確認ボタンが有効にならない
Contact Form 7 がフォームを描画した後に JavaScript が実行されているか確認してください。DOMContentLoaded で初期化しているので通常は問題ありませんが、CF7 が Ajax でフォームを読み込む設定になっている場合はタイミングがずれることがあります。
Q. 確認画面に値が表示されない
確認画面の data-name 属性と、入力フィールドの name 属性が一致しているか確認してください。CF7 はフィールド名の末尾にハイフンがつくことがありません( your-name はそのまま your-name になります)。
Q. 送信後にサンクスページに遷移しないwpcf7mailsent イベントが発火しているかブラウザの開発者ツールで確認してください。メール送信の設定(SMTP 等)に問題がある場合、このイベントは発火しません。Contact Form 7 の管理画面でメール設定を見直してください。
まとめ
Contact Form 7 で確認画面を実装するのに、追加プラグインは必要ありません。フォームテンプレート内に確認画面用の HTML を並べて配置し、JavaScript で表示を切り替えるだけで実現できます。
この方法のメリットは、プラグインの依存関係が増えないこと、CF7 の標準的なバリデーションや送信処理をそのまま使えること、そしてデザインを自由にカスタマイズできることです。
ぜひコピペして、自分のサイトに導入してみてください。