WordPressでAJAXを使用したメールフォームを作成する
Wordpressのwp_mailを使用したメール送信フォームを作成します。 確認画面はAJAXで動的に作成します。
目的
WordPressでメールフォームを自作します。
内容確認画面はページ遷移せずにJavascriptで表示し、確認画面で戻るボタンを押したら戻ります。
確認画面で送信ボタンを押したらAJAXを使用してメールを送信します。
AJAXはXMLHttpRequestを使用します。
メール送信はwp_mailを使用します
※セキュリティを考慮した入力チェックなどはここでは行わない(また今度)。やり方だけメモ
wp_mailを使用してメールフォームを作成する。wp_mailを使用する理由は以下
- SMTPの設定がプラグインにより簡単にできるため
- メールプラグインなど、他からのサイトへの影響を最小限にするため
自作する理由は以下
- Wordprssのメールプラグインはどれも高機能すぎててどれが自分の使いたい最小限機能なのか判別が難しいため
- 自分の好きなように作れるため(確認画面とかページ遷移したくない、そんなプラグインで自分に合うのがわからなかったため)
- jQueryのバージョン管理や、他のプラグインの干渉など管理工数を減らすため
結果
仕様概要
冒頭で記載したがもう一度仕様を書くと
- WordPressで動くメールフォームを自作します。
- 内容確認画面はページ遷移せずにJavascriptで表示します。
- 内容確認画面で戻るボタンを押したら確認画面は消えます。
- 内容確認画面で送るボタンを押したらAJAXを使用してメールを送信します。
- AJAXはXMLHttpRequestを使用します。
- メール送信はwp_mailを使用します。
- セキュリティを考慮した入力チェックなどはここでは行わない(また今度)。やり方だけメモ
イメージはこんな感じ。
※「送信する」を押すと確認画面を作ります。その後「Send」ボタンを押しても何もしません。「Back」ボタンで戻ってください。
▼前提 directory図
-function.php <--- 各外部ファイルの読み込みと関数実行
-single.php <--- 表示するページ(Javascriptはここに直書き)
-style.css <--- CSS
-inc(dir)
-post-mail.php <--- メール送信用プログラム(AJAXが参照するやつ)
HTML部分
html部分
<form id="fm1" name="myForm" onsubmit="return false;">
<label>name</label></br>
<input id="nm" type=textbox name="name" style="width:95%;"></br>
<label>address</label></br>
<input id="addr" type=textbox name="address" style="width:95%;" ></br>
<label>content</label></br>
<textarea id="ct" name="content" cols="50" rows="10" style="width:95%;height : 300px;"></textarea></br></br>
<input type="button" value="送信する" onclick="checkText();">
</form>
css部分
/******* FORMS *******************/
/******* Confirm Prompt **********/
.form-check {
z-index : 100;
background-color : #fff;
border : solid 1px #ccc;
border-radius : 3%;
width : 90%;
height : 90vh;
margin : auto ; padding : 5%;
position : fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
}
.form-check h1 {
text-align : center; }
.form-check .confirm-txt {
width : 100%;
border : solid 1px #ccc;
margin-bottom : 3%;
min-height : 10px; }
.control-send {
width : 90%;
text-align : center;
margin : auto ; padding : auto ;
margin-top : 5%;}
.control-send #send ,
.control-send #back {
display : inline-block;
max-width: 180px;
text-align: left;
border: 2px solid #9ec34b;
font-size: 16px;
color: #9ec34b;
text-decoration: none;
font-weight: bold;
padding: 8px 16px;
border-radius: 4px;
transition: .4s;
}
.control-send #send:hover ,
.control-send #back:hover {
background-color: #9ec34b;
border-color: #cbe585;
color: #FFF;
}
.control-send #back {
margin-right : 5%;}
/******* FORMS END ***************/
Javascript部分
<script type="text/javascript">
<!--- javascript argument ---->
var arg1 = "<?php bloginfo('template_directory') ?>" ;
</script>
<script>
function checkText() {
var tpath = arg1 ;
name = document.forms.fm1.nm.value;
address = document.forms.fm1.addr.value;
content = document.forms.fm1.ct.value;
htmlBody = document.getElementById('site-content');
checkForm = '<div id="form-check" class="form-check">'
+ '<h1>Confirm</h1>'
+ '<label>name</label>'
+ '<div class="confirm-txt">' + name + ' </div>'
+ '<label>address</label>'
+ '<div class="confirm-txt">' + address + ' </div>'
+ '<label>content</label>'
+ '<div class="confirm-txt">' + content.replace(/\r?\n/g,'<br>') + ' </div>'
+ '<div class="control-send">'
+ '<div id="back">Back </div>'
+ '<div id="send">Send</div>'
+ '</div>'
+ '</div>';
htmlBody.insertAdjacentHTML('afterbegin', checkForm);
// Control Back
document.getElementById("back").onclick = function() {
document.getElementById("form-check").remove();
}
// Control Send
document.getElementById("send").onclick = function() {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState === 4) {
// Establishment
console.log("now Establishment " + request.statusText);
} else {
// NOT Establishment
console.log("not Establishment " + request.statusText );
}
}
request.onload = function(){
console.log("complete " + request.responseText);
document.getElementById("form-check").remove();
document.forms.fm1.reset();
}
request.responseType = 'text';
request.open("POST", tpath + "/inc/post-mail.php", true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
request.send("name=" + name + "&addr=" + address + "&content=" + content);
}
}
</script>
PHP部分
<?php
require('../../../../wp-blog-header.php');
require_once("../../../../wp-config.php");
// chenge html mail
$name = $_POST["name"];
$address = $_POST["addr"];
$content = $_POST["content"];
$blogname = get_option( 'blogname' );
$headers = array( 'Content-Type: text/plain; charset=UTF-8','From: me Myself ' );
$subject = 'Contact Form からの送信';
$to = get_option('admin_email');
$body = "from " . $name . "(" . $address . ")" . "\n"
. $content;
wp_mail( $to, $subject, $body, $headers );
?>
wordpress部分
function set_mail_from( $email ) {
return 'XXXXXXXXX@webmemo.tokyo';
}
function set_mail_from_name( $email_from ) {
return 'master';
}
add_filter( 'wp_mail_from', 'set_mail_from' );
add_filter( 'wp_mail_from_name', 'set_mail_from_name' );
方法
フロー
1htmlでメールフォームを作成 |
↓ |
2Javascrptで確認画面を作成 |
↓ |
3PHPでメール送信プログラムを作成 |
↓ |
4AJAXで送信処理を作成 |
↓ |
5WordPressで送信設定を変更 |
htmlでメールフォームを作成
htmlで普通にフォームを作成する。
ボタンを押したときに動くJavascriptの関数はcheckText()という名称にした。
<form id="fm1" name="myForm" onsubmit="return false;">
<label>name</label></br>
<input id="nm" type=textbox name="name" style="width:95%;"></br>
<label>address</label></br>
<input id="addr" type=textbox name="address" style="width:95%;" ></br>
<label>content</label></br>
<textarea id="ct" name="content" cols="50" rows="10" style="width:95%;height : 300px;"></textarea></br></br>
<input type="button" value="送信する" onclick="checkText();">
</form>
エンターが押されても送信されないように<form onsubmit="return false;">とする
<form id="fm1" name="myForm" onsubmit="return false;">
ボタンを押したときだけJSが動くように<input type="button" onclick="checkText();">とする
<input type="button" value="送信する" onclick="checkText();">
</form>
Javascrptで確認画面を作成
確認画面と戻るボタンまでの処理
フォームのボタンを押すとform-checkクラスがついたhtmlを追加する。
site-contentは確認画面を追加するdiv、画面いっぱいに表示するためサイトを囲っているコンテナを指定。
function checkText() {
var tpath = arg1 ;
name = document.forms.fm1.nm.value;
address = document.forms.fm1.addr.value;
content = document.forms.fm1.ct.value;
htmlBody = document.getElementById('site-content');
checkForm = '<div id="form-check" class="form-check">'
+ '<h1>Confirm</h1>'
+ '<label>name</label>'
+ '<div class="confirm-txt">' + name + ' </div>'
+ '<label>address</label>'
+ '<div class="confirm-txt">' + address + ' </div>'
+ '<label>content</label>'
+ '<div class="confirm-txt">' + content.replace(/\r?\n/g,'<br>') + ' </div>'
+ '<div class="control-send">'
+ '<div id="back">Back </div>'
+ '<div id="send">Send</div>'
+ '</div>'
+ '</div>';
htmlBody.insertAdjacentHTML('afterbegin', checkForm);
// Control Back
document.getElementById("back").onclick = function() {
document.getElementById("form-check").remove();
}
}
戻るボタンを押したときの挙動、追加したform-checkを削除する。
間違いを修正するためにフォームの値はクリアしない。
document.getElementById("back").onclick = function() {
document.getElementById("form-check").remove();
}
確認画面で改行をhtml上で表示したいため<br>に変換する。
+ '<div class="confirm-txt">' + content.replace(/\r?\n/g,'<br>') + ' </div>'
PHPでメール送信プログラムを作成
<?php
require('../../../../wp-blog-header.php');
require_once("../../../../wp-config.php");
// chenge html mail
$name = $_POST["name"];
$address = $_POST["addr"];
$content = $_POST["content"];
$blogname = get_option( 'blogname' );
$headers = array( 'Content-Type: text/plain; charset=UTF-8','From: me Myself ' );
$subject = 'Contact Form からの送信';
$to = get_option('admin_email');
$body = "from " . $name . "(" . $address . ")" . "\n"
. $content;
wp_mail( $to, $subject, $body, $headers );
?>
WordPressの関数を使うためにConfigなどを読み込む
require('../../../../wp-blog-header.php');
require_once("../../../../wp-config.php");
wp_mailの引数
▼wp_mail()
値 | 説明 |
---|---|
$to | (文字列 | 配列) (必須) 送りたい宛先。配列またはコンマ区切りの文字列で複数の宛先を指定できます。 |
$subject | (文字列) (必須) メッセージの件名。 |
$message | (文字列) (必須) メッセージの本文。 |
$headers | (文字列 | 配列) (オプション) メッセージに付けて送るメールヘッダー。文字列形式の場合、各ヘッダー行(From: や Cc: 等で始まる)を改行で区切る("\r\n")。 |
$attachments | (文字列 | 配列) (オプション) 添付するファイル。形式は一つのファイル名、ファイル名の配列、または複数のファイル名を改行で区切った一つの文字列。 |
戻り値 | (真偽値) (必須) メールを正常に送信できたかどうか。 |
AJAXで送信処理を作成
<script type="text/javascript">
<!--- javascript argument ---->
var arg1 = "<?php bloginfo('template_directory') ?>" ;
</script>
<script>
function checkText() {
var tpath = arg1 ;
// Control Send
document.getElementById("send").onclick = function() {
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState === 4) {
// Establishment
console.log("now Establishment " + request.statusText);
} else {
// NOT Establishment
console.log("not Establishment " + request.statusText );
}
}
request.onload = function(){
console.log("complete " + request.responseText);
document.getElementById("form-check").remove();
document.forms.fm1.reset();
}
request.responseType = 'text';
request.open("POST", tpath + "/inc/post-mail.php", true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
request.send("name=" + name + "&addr=" + address + "&content=" + content);
}
}
</script>
以下、諸事情によりJavascriptにテンプレートディレクトリのパスを渡している。
<script type="text/javascript">
<!--- javascript argument ---->
var arg1 = "<?php bloginfo('template_directory') ?>" ;
</script>
var tpath = arg1 ;
状態監視、XMLHttpRequestの状態を監視している。
特に必須ではない。
request.onreadystatechange = function() {
if (request.readyState === 4) {
// Establishment
console.log("now Establishment " + request.statusText);
} else {
// NOT Establishment
console.log("not Establishment " + request.statusText );
}
}
接続できた場合の処理、確認画面の削除と、フォームのクリアを行う。
実行したphpでメール送信できなくてもここに入る。
request.onload = function(){
console.log("complete " + request.responseText);
document.getElementById("form-check").remove();
document.forms.fm1.reset();
}
AJAX実行処理
sendに渡したい引数と送る側で参照する変数名を記載する。
request.responseType = 'text';
request.open("POST", tpath + "/inc/post-mail.php", true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
request.send("name=" + name + "&addr=" + address + "&content=" + content);
setRequestHeaderをopenとsendの間に記述しないと以下のようなエラーが出た。
<b>Deprecated</b>: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead. in <b>Unknown</b> on line <b>0</b><br />
参考
以下、参考にさせていただきました。
その他詳細
WordPressで送信設定を変更
デフォルトでwordpressでメールを送ると、"Wordpress"と、サイトが何でできているかバレてしまう。
さすがにそれはいけないだろうと思い送信メール設定を変更する。
以下をfunction.phpに追加する。
function set_mail_from( $email ) {
return 'XXXXXXXXX@webmemo.tokyo';
}
function set_mail_from_name( $email_from ) {
return 'master';
}
add_filter( 'wp_mail_from', 'set_mail_from' );
add_filter( 'wp_mail_from_name', 'set_mail_from_name' );