Contact Form 7はデフォルトでは確認画面とサンクスページ(送信完了)が無く、多くの方はプラグイン「Contact Form 7 Multi-Step Forms」を使用するでしょう。
この記事でも以前に、「Contact Form 7で確認画面を作る方法【Multi-Step Formsの使い方】」という記事を書いてますが、
- 500文字以上の長文を送信できない
- ファイル添付ができない
- 1ページに複数フォームがある時に対応できない
こういった制約がありました。
今回紹介する方法は、Contact Form 7の確認画面とサンクスページをJavaScriptで自作するので、余計なプラグインも必要ないし、制約も何もありません。Web制作の実案件では確認画面の実装は非常によくあるため、この機会に自分のものにしておきましょう。

この記事を書いたのは
しょーご(@samurabrass)
当ブログ「しょーごログ」の運営者。2018年からWeb制作・フロントエンドエンジニアとして主にWordPressでのサイト制作やシステム開発のフロントエンドを担当。同時にブログとYouTubeで情報発信を行っている。駆け出しエンジニアのコーディング課題添削も行い、スクール講師を4年以上している経験を活かした分かりやすい記事制作を心がけている。
\現役エンジニアのレビュー付き/
実践レベルのコーディング課題公開中

- デザインカンプからのコーディングを経験したい
- 現役エンジニアのレビューを受けてみたい
- 即戦力級のポートフォリオを用意したい
2024年にデザインを完全リニューアルしています!
コーディングに自身をつけるにはプロからのレビューを貰うのが必須なため、制作会社も利用するレビューツールで添削をしています。

Web制作学習ロードマップにも取り入れているため、学習終了まで迷わず進むことが可能です。コーディングを本気で仕事したい方はぜひご活用ください!
\無料の入門編から本格企業サイトまで/
Contact Form 7の前準備

❶Contact Form 7に対応したHTMLを組んでおく
まず前提として、Contact Form 7が出力するHTML/CSSを先回りしたコーディングをしているのが重要です。
特にラジオボタンとチェックボックスは曲者です。
まだ理解できていない人は、以下の記事で勉強しておいてください。
❷サンクスページを用意しておく
今回は確認画面は別途用意する必要は無いですが、サンクスページは必要です。
よって、固定ページでサンクスページを作っておいてください。
Contact Form 7の動作イメージ確認
やりたいことを確認します。まずはContact Form 7を使用して以下のようなオリジナルデザインのフォームを準備します。
入力必須の項目を埋めないと、確認ボタンは押せません。

必須を全部埋めると、確認ボタンのdisabledが外れ、押せるようになります。

確認画面については遷移させる必要が無いので、「入力ページと同一ページ」にして、JSでページ内容を書き替えて表示します。
確認画面で入力内容が反映されているのが分かります。

「戻るボタン」「送信ボタン」の2つがあります。送信ボタンを押すと、サンクスページにリダイレクトさせます。

自動返信メールもファイルが添付されていることが確認できます。

サンクスページをわざわざ作る意味は、コンバージョン計測がしやすいからです。
広告のコンバージョン計測はサンクスページのアクセスで計測するので、結構必要なことが多いです。
Contact Form 7で確認画面を実装する流れ
❶HTML/CSSで作ったフォームをCF7タグに置き換える
まずデザインカンプ通りにHTML/CSSで組んだフォームをCF7で動くようにするため、
CF7のエディター内で各種inputやtextarea、ラジオボタン、チェックボックスなどをCF7のタグに置き換えましょう。
idやname、入力必須項目は必須は必ず付与してください。

あらかじめ「Contact Form 7で確認画面を作る方法【Multi-Step Formsの使い方】」で構築された方はタグに置き換えても表示崩れは無いかと思います。
表示が崩れた人は、CF7が吐き出すHTMLをよくみて再構築してみてください。
ラジオボタンとチェックボックスが特に注意です。
❷HTML/CSSを調整する
今回は確認画面も同一のページで出すので、確認画面のHTMLを書き足しておきます。
また、確認画面側の要素にはconfirm_〇〇という対応したクラス名をつけておきます。
一応HTMLを全部載せます。
- 確認画面ではinputなど入力部分をspanに変えている
- 送信ボタンは確認画面の方に置く
- CSSで確認画面はデフォルトでは非表示にしておく
<div class="Form">
<!-- 会社名input -->
<div class="Form-Item">
<p class="Form-Item-Label">
<span class="Form-Item-Label-Required">必須</span>会社名
</p>
[text* company_name id:company_name placeholder "例)株式会社令和"]
</div>
<!-- 名前input -->
<div class="Form-Item">
<p class="Form-Item-Label"><span class="Form-Item-Label-Required">必須</span>氏名</p>
[text* your_name id:your_name placeholder "例)山田太郎"]
</div>
<!-- 電話番号input -->
<div class="Form-Item">
<p class="Form-Item-Label"><span class="Form-Item-Label-Required">必須</span>電話番号</p>
[tel* tel id:tel placeholder "例)000-0000-0000"]
</div>
<!-- メールアドレスinput -->
<div class="Form-Item">
<p class="Form-Item-Label"><span class="Form-Item-Label-Required">必須</span>メールアドレス</p>
[email* email id:email placeholder "例)example@gmail.com"]
</div>
<!-- ラジオボタン -->
<div class="Form-Item">
<p class="Form-Item-Label"><span class="Form-Item-Label-Required">必須</span>ラジオボタン</p>
[radio radio id:radio default:1 "選択肢❶" "選択肢❷" "選択肢❸"]
</div>
<!-- チェックボックス -->
<div class="Form-Item">
<p class="Form-Item-Label"><span class="Form-Item-Label-Required">必須</span>チェックボックス</p>[checkbox* checkbox id:checkbox "選択肢1" "選択肢2" "選択肢3"]
</div>
<div class="Form-Item">
<p class="Form-Item-Label isMsg"><span class="Form-Item-Label-Required">必須</span>お問い合わせ内容</p>
[textarea* textarea id:textarea]
</div>
<!-- File添付 -->
<div class="Form-Item">
<p class="Form-Item-Label">ファイル添付</p>
[file file-670 id:file class:file]
</div>
<div class="button-wrap">
<input type="button" class="confirm_button" value="確認する" disabled>
</div>
</div>
<!-- 確認画面 -->
<div class="confirm_area">
<h2>入力内容確認</h2>
<p>以下の内容でよろしいですか?</p>
<!-- 会社名input -->
<div class="Form-Item">
<p class="Form-Item-Label">
<span class="Form-Item-Label-Required">必須</span>会社名
</p>
<span class="confirm_company_name"></span>
</div>
<!-- 名前input -->
<div class="Form-Item">
<p class="Form-Item-Label"><span class="Form-Item-Label-Required">必須</span>氏名</p>
<span class="confirm_your_name"></span>
</div>
<!-- 電話番号input -->
<div class="Form-Item">
<p class="Form-Item-Label"><span class="Form-Item-Label-Required">必須</span>電話番号</p>
<span class="confirm_tel"></span>
</div>
<!-- メールアドレスinput -->
<div class="Form-Item">
<p class="Form-Item-Label"><span class="Form-Item-Label-Required">必須</span>メールアドレス</p>
<span class="confirm_email"></span>
</div>
<!-- ラジオボタン -->
<div class="Form-Item">
<p class="Form-Item-Label"><span class="Form-Item-Label-Required">必須</span>ラジオボタン</p>
<span class="confirm_radio"></span>
</div>
<!-- チェックボックス -->
<div class="Form-Item">
<p class="Form-Item-Label"><span class="Form-Item-Label-Required">必須</span>チェックボックス</p><span class="confirm_checkbox"></span>
</div>
<div class="Form-Item">
<p class="Form-Item-Label isMsg"><span class="Form-Item-Label-Required">必須</span>お問い合わせ内容</p>
<span class="confirm_textarea"></span>
</div>
<!-- File添付 -->
<div class="Form-Item">
<p class="Form-Item-Label">ファイル添付</p>
<span class="confirm_file"></span>
</div>
<div class="button-wrap">
[submit "送信"]
<input type="button" class="back_button" value="戻る">
</div>
</div>
<!-- 完了画面 -->
<div class="thanks_area">
<h2>送信完了</h2>
<p>お問合せいただきありがとうございました。<br>
2営業日以内に担当者よりご返信差し上げます。</p>
</div>
/*確認画面と完了画面を非表示*/
.confirm_area,
.thanks_area {
display: none;
}
/*デフォルトのサンクスメッセージを非表示*/
.wpcf7-response-output{
display: none;
}
❸JavaScriptを書く
さてここからが最重要ポイントで、最難関ポイントです。
一旦JSを全部載せますので、コピペしてもらって構いません。
document.addEventListener('DOMContentLoaded', () => {
// 入力内容を格納するための変数
let val;
// 入力フィールドのタイプを格納するための変数
let type;
// ラジオボタンの選択値を格納するための変数
let radio;
// チェックボックスの選択値を格納するための変数
let check;
// ラジオボタンの初期値を取得し、確認画面に反映させる
const radioButtons = document.querySelectorAll('[type="radio"]:checked');
radioButtons.forEach(button => {
// ラジオボタンの選択値を取得
radio = button.value;
// ラジオボタンの親要素からidを取得
const id = button.closest('[id]').id;
// 取得したidをクラス名に追加し、確認画面の値を設定
document.querySelector(`.confirm_${id}`).textContent = radio;
});
// 入力フィールドの内容が変更された場合の処理
const formInputs = document.querySelectorAll('.Form-Item input, .Form-Item select, .Form-Item textarea');
formInputs.forEach(input => {
input.addEventListener('change', function () {
// 入力内容を取得
val = this.value;
// 入力フィールドのタイプを取得
type = this.getAttribute("type");
// ラジオボタンの場合の処理
if (type === "radio") {
// ラジオボタンの選択値を取得
radio = this.value;
// ラジオボタンの親要素からidを取得
const id = this.closest("[id]").id;
// 取得したidをクラス名に追加し、確認画面の値を設定
document.querySelector(`.confirm_${id}`).textContent = radio;
}// チェックボックスの場合の処理
else if (type === "checkbox") {
// チェックボックスの選択値を取得
check = this.value;
// チェックボックスの親要素からidを取得
const id = this.closest("[id]").id;
// 取得したidをクラス名に追加し、確認画面の値を設定
document.querySelector(`.confirm_${id}`).textContent += check + " / ";
}// その他の場合の処理
else {
// 入力フィールドのidを取得
const id = this.id;
// 取得したidをクラス名に追加し、確認画面の値を設定
document.querySelector(`.confirm_${id}`).textContent = val;
}
});
});
// 確認ボタンをクリックした場合の処理
const confirmButton = document.querySelector(".confirm_button");
confirmButton.addEventListener('click', () => {
document.querySelector(".Form").style.display = 'none';
document.querySelector(".confirm_area").style.display = 'block';
window.scrollTo(0, document.querySelector('#navi').getBoundingClientRect().top);
});
// 戻るボタンをクリックした場合の処理
const backButton = document.querySelector(".back_button");
backButton.addEventListener('click', () => {
document.querySelector(".Form").style.display = 'block';
document.querySelector(".confirm_area").style.display = 'none';
window.scrollTo(0, document.querySelector('#navi').getBoundingClientRect().top);
});
// 必須項目が変更された場合の処理
const requiredInputs = document.querySelectorAll('[aria-required="true"]');
requiredInputs.forEach(input => {
input.addEventListener('input', () => {
// フラグ
let flag = true;
// 必須項目をループで確認
requiredInputs.forEach(requiredInput => {
if (requiredInput.value === "") {
flag = false;
}
});
// フラグに基づいて確認ボタンを有効化/無効化
confirmButton.disabled = !flag;
});
});
// 送信ボタンをクリックした場合の処理
document.addEventListener('wpcf7mailsent', (event) => {
location = 'https://〇〇.com/thanks/';
}, false);
});
以下簡単な解説です。
初期値の設定
const radioButtons = document.querySelectorAll('[type="radio"]:checked');
radioButtons.forEach(button => {
// ここに初期値の設定処理が含まれています
});
ラジオボタンの初期値を取得して、確認画面に反映させます。
querySelectorAllを使用して、チェックされたラジオボタンをすべて選択し、それぞれのラジオボタンの値と ID を取得し、確認画面に表示します。
入力フィールドの変更イベントのリスナーの追加
const formInputs = document.querySelectorAll('.Form-Item input, .Form-Item select, .Form-Item textarea');
formInputs.forEach(input => {
input.addEventListener('change', function () {
// ここに入力フィールドの変更時の処理が含まれています
});
});
入力フィールド(input、select、textarea)の内容が変更されたときに実行される処理を追加します。
changeイベントが発生するたびに、入力された値が取得され、それに応じて確認画面の表示が更新されます。
確認ボタンのクリックイベントのリスナーの追加
const confirmButton = document.querySelector(".confirm_button");
confirmButton.addEventListener('click', () => {
// ここに確認ボタンがクリックされたときの処理が含まれています
});
確認ボタンがクリックされたときに実行される処理を追加します。この場合、入力フォームが非表示になり、確認画面が表示されるようになります。
戻るボタンのクリックイベントのリスナーの追加
const backButton = document.querySelector(".back_button");
backButton.addEventListener('click', () => {
// ここに戻るボタンがクリックされたときの処理が含まれています
});
戻るボタンがクリックされたときに実行される処理を追加します。この場合、確認画面が非表示になり、入力フォームが再び表示されるようになります。
必須項目の変更イベントのリスナーの追加
const requiredInputs = document.querySelectorAll('[aria-required="true"]');
requiredInputs.forEach(input => {
input.addEventListener('input', () => {
// ここに必須項目が変更されたときの処理が含まれています
});
});
必須項目の内容が変更されたときに実行される処理を追加します。
これにより、必須項目がすべて入力されているかどうかを確認し、確認ボタンの有効性を制御します。
送信ボタンのクリックイベントのリスナーの追加
document.addEventListener('wpcf7mailsent', (event) => {
// ここに送信ボタンがクリックされたときの処理が含まれています
}, false);
送信ボタンがクリックされたときに実行される処理を追加します。
この場合、フォームが正常に送信された後、指定された場所にリダイレクトされるようになります。
❹JavaScriptのクラス名を自分のHTMLのに合わせる
ここから自分のHTMLに合わせてJavaScriptを書き換えます。
と言っても、クラス名とサンクスページのリダイレクト先を書き換えるだけです。
まず以下の確認ボタンと戻るボタン処理のクラス名部分は、自分のに変えてください。
// 確認ボタンをクリックした場合の処理
const confirmButton = document.querySelector(".confirm_button");
confirmButton.addEventListener('click', () => {
document.querySelector(".Form").style.display = 'none';
document.querySelector(".confirm_area").style.display = 'block';
window.scrollTo(0, document.querySelector('#navi').getBoundingClientRect().top);
});
// 戻るボタンをクリックした場合の処理
const backButton = document.querySelector(".back_button");
backButton.addEventListener('click', () => {
document.querySelector(".Form").style.display = 'block';
document.querySelector(".confirm_area").style.display = 'none';
window.scrollTo(0, document.querySelector('#navi').getBoundingClientRect().top);
});
ここのクラス名も同様です。
// 入力フィールドの内容が変更された場合の処理
const formInputs = document.querySelectorAll('.Form-Item input, .Form-Item select, .Form-Item textarea');
送信後のサンクスページURLも自分のものに変えてください。
// 送信ボタンをクリックした場合の処理
document.addEventListener('wpcf7mailsent', (event) => {
location = 'https://〇〇.com/thanks/';
}, false);
❺メール設定
最後にメール設定をプラグイン設定ページより行ってください。
メールタグの名前はnameと紐づいているので、人によって異なります。
これをいれることで、メール内容に反映されます。

❻動作確認
最後に動作確認をして終了です。
- 戻るボタンが機能している
- 確認画面で全てのデータが反映されている
- 送信してリダイレクトする
- メールが届く(ファイル含め)
制限の無いお問い合わせフォームへ

今回はContact Form 7の確認画面をプラグイン無しで実装する方法を紹介しました。ほとんどどんなお問い合わせフォームでも対応可能なため、Web制作を独学している方、デイトラなどのWeb制作スクールに通っている方もぜひ参考にしてください。
JavaScriptの部分が難関かと思いますが、クラス名を入れ替えるのが大半なので、ゆっくり焦らず読解してみてください。AIにコーディングを補助してもらう方法を以前解説しているので、そちらを使えばスムーズかと思います。
また、私が出している【上級】デザインカンプからのコーディング実践演習【WordPress実案件レベル】でのお問い合わせフォームに導入して実践してみるのもいいかと思います。

HTML初心者からWordPress実案件レベルまでのコーディング演習課題を「専用ページ」にて公開しています。

- Figma,Photoshopデザインからのコーディング
- サーバーアップロードでサイト公開
- プロによる最大3回の表示確認特典
- レビュー返しは爆速
- 2024年にデザイン刷新!被らないポートフォリオ
「初級編」は初めてデザインからコーディングする方向け
「中級編」はJavaScriptやjQueryの練習
「上級編」はWordPressの実案件を模擬体験できるレベル感にしています。
中級者の方には高難易度課題を詰め合わせた「即戦力セット」も出しています。
全課題で「実務レベルの、プロの厳しいレビュー」を受けられるようにしています。
また、2024年には随時デザインの刷新をしており、完全リニューアル!!
他者と差をつけられるポートフォリオが準備できます!

制作会社も使用する専用レビューツールで分かりやすく添削していきます!
基本的に「まとめて購入」していただくとかなりお得になります↓

コーディングは書籍だけではなかなか実力がつかないので、実務レベルのレビューを受けて自身をつけたい人は是非挑戦してみてください!

\課題の購入はこちらから/
ご寄付を頂けると今後の更新の励みになります!