Contact Form 7には、入力内容を送信前に一覧で確認する画面が標準では用意されていません。
確認画面用のプラグインを追加する方法もありますが、案件によっては、既存フォームのHTMLやデザインに合わせにくいことがあります。そこでこの記事では、JavaScriptを使い、入力画面と確認画面を同じページ内で切り替える方法を紹介します。
今回のコードは、次の項目に対応しています。
- テキスト、メール、電話番号、テキストエリア
- セレクトボックス
- ラジオボタン
- 複数選択できるチェックボックス
- 添付ファイル名の表示
- 入力画面へ戻ったときの値の保持
- 1ページに複数のContact Form 7がある場合
- 送信成功後のサンクスページへの移動
完成コードを順番に紹介するので、自分のフォーム項目に合わせて変更してください。
もくじ
実装する確認画面の仕組み
今回作る確認画面は、別ページへ移動するものではありません。
- 入力画面で必要事項を入力する
- 「入力内容を確認する」を押す
- 同じページ内で入力画面を隠し、確認画面を表示する
- 「修正する」で入力画面へ戻る
- 「この内容で送信する」でContact Form 7から送信する
- 送信に成功した場合だけサンクスページへ移動する
JavaScriptは表示を切り替えるだけです。実際のメール送信やサーバー側の検証は、Contact Form 7に任せます。
1. Contact Form 7のフォームを作る
WordPressの管理画面から「お問い合わせ」→「コンタクトフォーム」を開き、フォームタブへ次のコードを設定します。
<div class="cf7-confirm-form" data-thanks-url="/thanks/">
<div class="cf7-input-screen">
<div class="form-row">
<label for="your-name">お名前 <span class="required">必須</span></label>
[text* your-name id:your-name autocomplete:name]
</div>
<div class="form-row">
<label for="your-email">メールアドレス <span class="required">必須</span></label>
[email* your-email id:your-email autocomplete:email]
</div>
<div class="form-row">
<label for="your-tel">電話番号</label>
[tel your-tel id:your-tel autocomplete:tel]
</div>
<div class="form-row">
<span class="form-label">お問い合わせ種別 <span class="required">必須</span></span>
[radio inquiry-type use_label_element default:1 "制作の相談" "更新・保守" "その他"]
</div>
<div class="form-row">
<span class="form-label">ご希望の連絡方法</span>
[checkbox contact-method use_label_element "メール" "電話" "オンラインミーティング"]
</div>
<div class="form-row">
<label for="your-subject">件名 <span class="required">必須</span></label>
[text* your-subject id:your-subject]
</div>
<div class="form-row">
<label for="your-message">お問い合わせ内容 <span class="required">必須</span></label>
[textarea* your-message id:your-message]
</div>
<div class="form-row">
<label for="your-file">添付ファイル</label>
[file your-file id:your-file filetypes:jpg|jpeg|png|pdf limit:5mb]
</div>
<div class="form-actions">
<button type="button" class="cf7-confirm-button">入力内容を確認する</button>
</div>
</div>
<div class="cf7-confirm-screen" hidden>
<h2 class="cf7-confirm-title" tabindex="-1">入力内容の確認</h2>
<p>以下の内容でよろしければ、「この内容で送信する」を押してください。</p>
<dl class="confirm-list">
<div class="confirm-row">
<dt>お名前</dt>
<dd data-confirm-for="your-name"></dd>
</div>
<div class="confirm-row">
<dt>メールアドレス</dt>
<dd data-confirm-for="your-email"></dd>
</div>
<div class="confirm-row">
<dt>電話番号</dt>
<dd data-confirm-for="your-tel"></dd>
</div>
<div class="confirm-row">
<dt>お問い合わせ種別</dt>
<dd data-confirm-for="inquiry-type"></dd>
</div>
<div class="confirm-row">
<dt>ご希望の連絡方法</dt>
<dd data-confirm-for="contact-method"></dd>
</div>
<div class="confirm-row">
<dt>件名</dt>
<dd data-confirm-for="your-subject"></dd>
</div>
<div class="confirm-row">
<dt>お問い合わせ内容</dt>
<dd data-confirm-for="your-message"></dd>
</div>
<div class="confirm-row">
<dt>添付ファイル</dt>
<dd data-confirm-for="your-file"></dd>
</div>
</dl>
<div class="form-actions">
<button type="button" class="cf7-back-button">入力内容を修正する</button>
[submit class:cf7-submit-button "この内容で送信する"]
</div>
</div>
</div>
確認欄はname属性と対応させる
確認画面のdata-confirm-forには、対応するContact Form 7タグのフィールド名を指定します。
[text* your-name]
<dd data-confirm-for="your-name"></dd>
項目を追加するときも、この2つを同じ名前にしてください。JavaScript側に項目ごとのクラス名を追加する必要はありません。
ファイルの種類と容量を必ず指定する
添付ファイルには、許可する拡張子と最大容量を明示します。
[file your-file filetypes:jpg|jpeg|png|pdf limit:5mb]
Contact Form 7公式では、filetypesとlimitを省略した場合の初期値は将来変更される可能性があるため、明示的な指定が推奨されています。
メールへ添付する場合は、「メール」タブの「ファイル添付」に次のメールタグも設定してください。
[your-file]
2. 確認画面のCSSを追加する
以下は基本的な表示例です。実際のサイトでは、色や幅をデザインに合わせて変更してください。
.cf7-confirm-screen[hidden],
.cf7-input-screen[hidden] {
display: none;
}
.form-row {
margin-bottom: 24px;
}
.form-row label,
.form-label {
display: block;
margin-bottom: 8px;
font-weight: 700;
}
.required {
display: inline-block;
margin-left: 6px;
padding: 2px 6px;
border-radius: 3px;
background: #c93434;
color: #fff;
font-size: 12px;
}
.form-row input[type="text"],
.form-row input[type="email"],
.form-row input[type="tel"],
.form-row select,
.form-row textarea {
box-sizing: border-box;
width: 100%;
padding: 12px;
border: 1px solid #b8c2cc;
border-radius: 5px;
font: inherit;
}
.confirm-list {
margin: 24px 0;
border-top: 1px solid #d8dee4;
}
.confirm-row {
display: grid;
grid-template-columns: minmax(140px, 30%) 1fr;
border-bottom: 1px solid #d8dee4;
}
.confirm-row dt,
.confirm-row dd {
margin: 0;
padding: 16px;
}
.confirm-row dt {
background: #f3f6f8;
font-weight: 700;
}
.confirm-row dd {
white-space: pre-wrap;
overflow-wrap: anywhere;
}
.form-actions {
display: flex;
justify-content: center;
gap: 16px;
margin-top: 32px;
}
.cf7-confirm-button,
.cf7-back-button,
.cf7-submit-button {
min-width: 200px;
padding: 13px 20px;
border: 0;
border-radius: 5px;
font: inherit;
font-weight: 700;
cursor: pointer;
}
.cf7-confirm-button,
.cf7-submit-button {
background: #176da3;
color: #fff;
}
.cf7-back-button {
background: #e9edf0;
color: #263746;
}
.cf7-confirm-button:focus-visible,
.cf7-back-button:focus-visible,
.cf7-submit-button:focus-visible {
outline: 3px solid #f0b429;
outline-offset: 3px;
}
@media (max-width: 600px) {
.confirm-row {
grid-template-columns: 1fr;
}
.confirm-row dt,
.confirm-row dd {
padding: 12px;
}
.form-actions {
flex-direction: column-reverse;
}
.cf7-confirm-button,
.cf7-back-button,
.cf7-submit-button {
width: 100%;
}
}
3. JavaScriptで入力内容を確認画面へ反映する
次のJavaScriptを、テーマのJavaScriptファイルなどへ追加します。
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('.wpcf7').forEach((wpcf7) => {
const form = wpcf7.querySelector('form.wpcf7-form');
const root = wpcf7.querySelector('.cf7-confirm-form');
if (!form || !root) {
return;
}
const inputScreen = root.querySelector('.cf7-input-screen');
const confirmScreen = root.querySelector('.cf7-confirm-screen');
const confirmButton = root.querySelector('.cf7-confirm-button');
const backButton = root.querySelector('.cf7-back-button');
const confirmTitle = root.querySelector('.cf7-confirm-title');
if (
!inputScreen ||
!confirmScreen ||
!confirmButton ||
!backButton
) {
return;
}
const getFieldValues = (fieldName) => {
const fields = form.querySelectorAll(
`[name="${CSS.escape(fieldName)}"], ` +
`[name="${CSS.escape(fieldName)}[]"]`
);
if (!fields.length) {
return [];
}
const firstField = fields[0];
if (firstField.type === 'file') {
return Array.from(firstField.files || []).map((file) => file.name);
}
if (firstField.type === 'radio' || firstField.type === 'checkbox') {
return Array.from(fields)
.filter((field) => field.checked)
.map((field) => field.value);
}
if (firstField.tagName === 'SELECT' && firstField.multiple) {
return Array.from(firstField.selectedOptions).map(
(option) => option.text
);
}
return [firstField.value.trim()].filter(Boolean);
};
const updateConfirmScreen = () => {
root.querySelectorAll('[data-confirm-for]').forEach((output) => {
const fieldName = output.dataset.confirmFor;
const values = getFieldValues(fieldName);
output.textContent = values.length ? values.join('、') : '未入力';
});
};
const showInputScreen = () => {
confirmScreen.hidden = true;
inputScreen.hidden = false;
};
const showConfirmScreen = () => {
updateConfirmScreen();
inputScreen.hidden = true;
confirmScreen.hidden = false;
confirmTitle?.focus({ preventScroll: true });
root.scrollIntoView({
behavior: window.matchMedia('(prefers-reduced-motion: reduce)').matches
? 'auto'
: 'smooth',
block: 'start',
});
};
confirmButton.addEventListener('click', () => {
if (!form.checkValidity()) {
form.reportValidity();
return;
}
showConfirmScreen();
});
backButton.addEventListener('click', () => {
showInputScreen();
root.scrollIntoView({
behavior: window.matchMedia('(prefers-reduced-motion: reduce)').matches
? 'auto'
: 'smooth',
block: 'start',
});
confirmButton.focus({ preventScroll: true });
});
wpcf7.addEventListener('wpcf7invalid', () => {
showInputScreen();
});
wpcf7.addEventListener('wpcf7mailfailed', () => {
showConfirmScreen();
});
wpcf7.addEventListener('wpcf7spam', () => {
showConfirmScreen();
});
wpcf7.addEventListener('wpcf7mailsent', () => {
const thanksUrl = root.dataset.thanksUrl;
if (thanksUrl) {
window.location.assign(thanksUrl);
}
});
});
});
この実装で押さえているポイント
確認画面を安定して動かすには、フォームごとに処理範囲を分けることが重要です。ページ全体から入力欄を取得すると、1ページに複数のフォームがある場合に、入力値やボタンの処理が衝突する可能性があります。
このコードでは、.wpcf7ごとに初期化し、そのフォーム内だけを検索しています。そのため、同じページに複数のContact Form 7を設置しても、それぞれ独立して動作します。
チェックボックスの値を毎回作り直す
値を文字列へ追加し続ける実装では、チェックを付けたり外したりすると、確認画面に同じ値が複数回表示されることがあります。
今回のコードでは、確認ボタンを押した時点でチェック済みの項目を取得し直します。
return Array.from(fields)
.filter((field) => field.checked)
.map((field) => field.value);
これにより、確認画面には現在選択されている値だけが表示されます。
idではなくname属性で対応させる
ラジオボタンやチェックボックスでは、Contact Form 7が複数のinput要素を出力します。単一のidを前提にすると、意図しない要素を取得する可能性があります。
確認欄のdata-confirm-forとフォームのnameを対応させることで、同じ名前を持つ選択肢をまとめて取得できます。
入力必須だけでなく入力形式も確認する
空文字だけを調べるコードでは、メールアドレスやURLの入力形式まで判定できません。
今回のコードでは、ブラウザ標準のcheckValidity()とreportValidity()を利用します。
if (!form.checkValidity()) {
form.reportValidity();
return;
}
ただし、ブラウザ側の検証だけで安全性を確保できるわけではありません。最終的な検証と送信処理はContact Form 7とサーバー側で行います。
送信の成否で画面を制御する
送信ボタンを押した時点でサンクスページへ移動してはいけません。入力エラー、スパム判定、メール送信失敗の場合にも移動してしまうためです。
Contact Form 7がメール送信に成功したときに発火するwpcf7mailsentを利用します。
wpcf7.addEventListener('wpcf7mailsent', () => {
window.location.assign('/thanks/');
});
公式ドキュメントによると、wpcf7mailsentはAjax送信が完了し、メールも送信された場合に発火します。
4. サンクスページを用意する
固定ページなどで、送信完了後に表示するページを作ります。
今回のフォームでは、最初の要素に移動先を指定しています。
<div class="cf7-confirm-form" data-thanks-url="/thanks/">
サイト構成に合わせて/thanks/を変更してください。
なお、Contact Form 7公式では、GA4のコンバージョン計測だけを目的とするなら、サンクスページへ移動しなくてもwpcf7mailsentでイベントを計測できると案内されています。
ユーザーへの完了案内や広告計測など、サンクスページが必要な理由を確認してから利用しましょう。
5. メール設定を確認する
フォームを作ったら、「メール」タブにフォームタグと同じ名前のメールタグを設定します。
お名前:[your-name]
メールアドレス:[your-email]
電話番号:[your-tel]
お問い合わせ種別:[inquiry-type]
ご希望の連絡方法:[contact-method]
件名:[your-subject]
お問い合わせ内容:
[your-message]
ファイルをメールへ添付する場合は、「ファイル添付」欄へ次を設定します。
[your-file]
確認画面に値が表示されても、メール設定にタグがなければ受信メールには入りません。必ずテスト送信して確認してください。
6. 動作確認する項目
公開前に、最低限次の項目を確認します。
入力と確認画面
- 必須項目が空の状態では確認画面へ進まない
- メールアドレスの形式が正しくない場合にエラーになる
- ラジオボタンの選択値が表示される
- チェックボックスを付け直しても値が重複しない
- textareaの改行が確認画面で維持される
- 添付ファイル名が表示される
- 「入力内容を修正する」で値を保持したまま戻れる
送信
- 正常送信後だけサンクスページへ移動する
- Contact Form 7のメールが管理者へ届く
- 自動返信メールが届く
- 添付ファイルがメールへ添付される
- スパム判定や送信失敗時にはサンクスページへ移動しない
表示と操作
- スマートフォンで表が横にはみ出さない
- Tabキーだけでボタンを操作できる
- 確認画面へ移動したことをキーボード利用者が認識できる
- JavaScriptのコンソールエラーが出ていない
JavaScriptが動かないときの確認方法
Contact Form 7のDOMイベントは、Ajax送信時に発火します。wpcf7mailsentが動かない場合は、まずContact Form 7のJavaScriptとWordPress REST APIが正常に利用できるか確認してください。
次の点も確認します。
- ブラウザの開発者ツールにJavaScriptエラーが出ていないか
- キャッシュ・最適化プラグインでJavaScriptの実行順が変わっていないか
.wpcf7や.cf7-confirm-formが実際のHTMLに存在するか- JavaScriptファイルがフォームのあるページで読み込まれているか
- サンクスページのURLが正しいか
エラーがあるときは、最初のエラーから順番に解消してください。
まとめ
Contact Form 7の確認画面は、プラグインを追加しなくてもJavaScriptで実装できます。
大切なのは、見た目だけ確認画面へ切り替えることではありません。
- フォームごとに処理を分ける
- 選択項目の現在値を正しく取得する
- 入力検証を省略しない
- 送信成功後だけサンクスページへ移動する
- キーボード操作やスマートフォン表示を確認する
この点を押さえることで、実案件でも調整しやすい確認画面になります。
まずはステージング環境で実装し、項目の入力、確認、修正、送信、メール受信まで一通りテストしてから本番へ反映してください。
