WordPress：Contact Form 7 add confirmでスクロール（Contact Form 7 v5.0~対応版）

#Contact Form 7 add confirmについて

[アイティーエー株式会社](https://www.eyeta.jp/)が作成している（たぶん）Contact Form 7拡張プラグイン。
[WordPress公式（プラグインページ）](https://wordpress.org/plugins/contact-form-7-add-confirm/)

##なにをするプラグインか？

前述の通り、お問い合わせフォームをWordPress上で作成することができるプラグインである[Contact Form 7](https://contactform7.com/ja/)に確認画面を追加することができるプラグイン。
確認画面がなぜContact Form 7に最初からないのかについては、承認確認チェックボックスがあるからいらないでしょとかそんな感じだったようなないような
[ソースはこれから探します。](https://togetter.com/li/156887)

Contact Form 7のカスタマイズで自分がやっていることについてはそのうちまた別記事にします。

##プラグインそのままでは使えないのか

**Contact Form 7は[今年1月に大型アップデートをしました。（バージョン5.0）](https://contactform7.com/ja/2018/01/31/contact-form-7-50/)**
このとき、正式にDOMイベントが実装された代わりに、これまでと発火の仕方が変わりました。

そこで、Contact Form 7をカスタマイズするソースについても色々と変える必要がでてきました。
その中の一つが今回カスタマイズするContact Form 7 add confirmです。

[プラグイン紹介ページ](https://www.eyeta.jp/archives/908)によると、修正が全然追いついていない様子。
実際にプラグインそのままで使ってみましたが、functions.phpがContact Form 7以前に合わせたソースのままですと、
スクロールが機能していなかったり、確認画面で動作させる関数を通っていなかったりと色々と危ない感じです。

なので、そのうちの一つである**スクロールを動作させるようにしよう**ということです。

「Contact Form 7 add confirmを使って確認画面でスクロールする方法！」みたいなのはいくつかヒットするんですが、
どれもバージョン5.0以前のものばかりなので、今では使えないものがほとんどだと思います。

#実装

##やりたいこと

- 入力画面でエラー
- 入力画面→確認画面へ遷移
- 確認画面→入力画面へ遷移

これらのときにフォームの一番上にスクロールするようにします。

なお、前提条件として今回は完了画面は別ページを用意しているものとします。
完了画面なくてもこれをもとにうまいことできると思います。

##用意するファイル

- 入力画面・確認画面用テンプレート

今回はpage-form.phpとしてます。

- カスタマイズ用jsファイル

今回はform.jsとしてます。

- プラグイン

**言わずもがなContact Form 7とContact Form 7 add confirmはインストールして有効化しといてください。**

##ソース

```page-form.php
/**
 * ヘッダーとかそのへんの記述は省略
**/ ?>

<section class="detail">
    <div class="inner">
        <div id="form_area">
            <div id="announce">
                <p>お電話でのお問い合わせは下記の番号よりお願いいたします。</p>
                <p>0xx-xxxx-xxxx</p>
            </div>
            <div>
                <p>その他のお問い合わせは下記フォームよりお願いいたします。</p>
            </div>
<?php echo do_shortcode('[contact-form-7 id="999" title="お問い合わせ"]'); ?>
        </div>
    </div>
</div>
<?
get_footer();
wp_footer();
<script type="text/javascript" src="/js/form.js"></script>
?>
```

当たり前のように`do_shortcode()`してますが、
テンプレート内でContact Form 7で登録したフォームを呼び出すにはこうします。
ググったらすぐ出てくると思います。

ミソは**`wp_footer()`のあとに自作jsを呼び出していること**。
`wp_footer()`内でContact Form 7 add confirmのjsを呼び出しているので、
**自作jsを後に呼び出さないとカスタマイズ（オーバーライドするだけだけど）が効かない**です。

```form.js
// v5.0からその他設定ではなく、イベントリスナーで各遷移時の処理を記述する
document.addEventListener( 'wpcf7submit', function( event ) {
	switch ( event.detail.status ) {
		case 'wpcf7c_confirmed':
			// 確認画面遷移時の処理
			break;
		case 'mail_sent':
			// メール送信完了時の処理
			break;
		case 'validation_failed':
			// エラー時の処理
			// エラー文の表示 (別関数)
			error_disp();
			// スクロール
			var adjust = $('#header').height();
			scrolltoFormTop('error', adjust);
			break;
	}
}, false );

// スクロール
scrolltoFormTop = function(status, adjust) {
	var $target = status == 'confirm' ? $('.detail') : $('#form_area');
	$("html,body").animate({ scrollTop: $target.offset().top - adjust }, 1000 ,"swing");
}

wpcf7c_scroll = function(unit_tag) {
	// Contact Form 7 add confirmのオーバーライド
			var adjust = $('#header').outerHeight(true) + $('#announce').outerHeight(true);
			var status = 'confirm';
			// 確認画面から入力画面への遷移時は基点をエラー時と同じように
			if (!$('.detail').hasClass('confirm')) {
				status = 'input';
				adjust = $('#header').outerHeight(true);
			}
			scrolltoFormTop(status, adjust);
}
```

PC画面とSP画面でヘッダーメニューの高さが異なる場合を想定しています。
（ヘッダー箇所は`id="header"`とします。）

ここでやっているのは、Contact Form 7 add confirmのスクロール処理が思うように動作しなかったので、
自前のスクロール処理を作成し、オーバーライドでその処理を通るようにしています。

そのままフォーム（`id="form_area"`）の先頭箇所までスクロールすると、
固定ヘッダーの場合、最初のほうの項目がヘッダーに隠れてしまうので、
ヘッダーの高さを取得して、そのぶんずらすようにしています。

また、入力画面と確認画面でスクロール基点も変わっています。
確認画面では「お電話でのお問い合わせは～」の箇所まで戻る必要ないので。

入力画面、完了画面ともに同じ位置にスクロールするようにしたければ

```
			// 確認画面から入力画面への遷移時は基点をエラー時と同じように
			if (!$('.detail').hasClass('confirm')) {
				status = 'input';
				adjust = $('#header').height();
			}
```
ここバッサリ削っていいかと思います。

#最後に
jQueryほとんど触らないのでいい勉強になりました。
jQueryに自信ニキからのご指摘受け付けております。

当プラグイン開発されてる方々の今後の更新を応援しております。