2020/05/06 22:22
「ajax」でページ遷移しない「お気に入り追加」ボタンフォームを簡単作成
非同期通信と言えば「ajax」とか「pjax」とかいろいろ出てくるんですが、一番手軽にajaxで少ないコードで非同期通信させる方法を書いておきます。
やりたかった事フロー
BtoBの会員サイト等で「A社」様が「B社」のページを見て
「あ、ここの店ええやん、また使いたいわぁ」っていう時を想定したものとなります。
で、その店舗を「お気に入りに追加」できるような仕様ができればと。
①お気に入り格納スペース作成
まずデータベース枠に「お気に入り」に追加した店舗を配列に格納していく場所を作成。
この辺に関してはDBに関する話になるので割愛します。
②配列で追加
お気に入りボタンを押すとDBへ配列で記事番号が追加されていく仕様にします。
③お気に入りボタンを作成
フォームを作って、SUBMITボタンを押すとPHPが発動してDBへの追加処理が走る…みたいな。
まずはその辺の処理ができてる事が今回の前提となります。
ajaxのコード記述例
という訳で前置きが長くなりましたがコードはこんな感じにしました。
【index.php】
<form action="<?php echo home_url('');?>/test" method="post" class="favorite-form">
<!-- DB処理の為に投稿ID(店舗ページ識別用ID)を隠し項目で取得 -->
<input type="hidden" name="postid" value="<?php echo get_the_ID();?>">
<!-- 既にお気に入りに追加されてるかどうかを判断 -->
<?php if (in_array($postid, $favorite_btn)):?>
<div class="c-post-favorite-form">
<!-- 追加されてたら削除用ボタン一式を表示 隠し項目に「削除」判断用の記述 -->
<input class="c-post-favoritetype" type="hidden" name="favoritetype" value="deleteFavorite">
<button type="submit" class="c-main-btn-link-del"><i class="fas fa-times"></i> お気に入り削除</button>
</div>
<?php else:?>
<div class="c-post-favorite-form">
<!-- なければ追加用ボタン一式を表示 隠し項目に「追加」判断用の記述 -->
<input class="c-post-favoritetype" type="hidden" name="favoritetype" value="addFavorite">
<button type="submit" class="c-main-btn-link"><i class="fas fa-plus"></i> お気に入り追加</button>
</div>
<?php endif;?>
</form>
<script type="text/javascript">
$(function(){
$('.favorite-form').submit(function(event) { //指定のclassのボタンがSUBMITされたら
event.preventDefault(); // HTMLでの送信をキャンセル。これがないとページ遷移してしまう
var index = $(".favorite-form").index(this); //何個目のフォームかを判断
var form = $('.favorite-form'); //フォームを変数に格納
var url = $(form[index]).attr('action'); //フォーム内のアクション要素を取得
var serialize = $(form[index]).serialize(); //フォーム内の全項目内容を取得。(form内のinputの値をまとめて取得)
var button = $(form[index]).find('button'); //押下前と後でボタンのスタイルを切り替える為に指定
var formarea = $('.c-post-favorite-form'); //切り替えるボタンを囲っている要素を指定しておく
var favoritetypeform = $('.c-post-favoritetype'); //ボタンを押した時の隠し項目を指定
var favoritetype = $(favoritetypeform[index]).val(); //隠し項目の中身を取得(後に分岐させる為)
if(favoritetype == 'deleteFavorite') { //隠し項目の中で分岐させ、押下前と後のボタン一式を切り替える。アラート表示も変える
var favoritealert = 'お気に入りから削除しました';
var favoritetag = '<input class="c-post-favoritetype" type="hidden" name="favoritetype" value="addFavorite"><button type="submit" class="c-main-btn-link"><i class="fas fa-plus"></i> お気に入り追加</button>';
} else {
var favoritealert = 'お気に入りに追加しました';
var favoritetag = '<input class="c-post-favoritetype" type="hidden" name="favoritetype" value="deleteFavorite"><button type="submit" class="c-main-btn-link-del"><i class="fas fa-times"></i> お気に入り削除</button>';
}
$.ajax({
type: 'POST', //methodの種類を指定。GETかPOST
url: url, //上記で取得したアクションが指定される
data: serialize, //フォーム内の全項目の内容が指定される
dataType: 'html' //利用可能なデータのタイプはtext、html、xml、 json、jsonp、script
})
// ajax通信成功時の処理
.done(function(data){ //通信成功後
alert(favoritealert); //上記分岐で指定したアラートを表示
$(formarea[index]).html(favoritetag); //更にボタン箇所が上記分岐で指定したタグに切り替わる
})
// ajax通信成失敗の処理
.fail(function(){ //通信に失敗した時
alert('エラーが発生しました');
})
return false; //これがないとページ遷移してしまう
});
});
</script>
スクリプトの記述もindex内に一緒に書いてますが、別に切り分けててもいいと思います。
ただ、このページ以外では使わないものになるので、毎回読む必要もないものなんで一緒に書いてる感じ。
ゴチャゴチャと書いてますが、ajaxを通信させる為に必要なのは基本的にコレだけです↓
【簡素バージョン index.php】
$(function(){
$('.favorite-form').submit(function(event) {
event.preventDefault();
var form = $(this);
var url = form.attr('action');
var method = form.attr('method');
var serialize = form.serialize();
$.ajax({
type: method,
url: url,
data: serialize,
dataType: 'html'
.done(function(data){ // ajax通信成功時
//ココに記述
})
.fail(function(){ // ajax通信成失敗
//ココに記述
})
return false;
});
});
DB(データベース)内でお気に入り情報を変更
お次はフォーム内のボタンが押された時に動く処理をするページを作ります。
このページ内に「お気に入りボタンが押された時」の内容を変更する記述を書きます。
例えば、「追加」が押された時の処理、「削除」が押された時の処理、などです。
※DBにあらかじめ「$favorite」という枠を作っておく必要があります(今回は作成方法は紹介してません)
DBにオリジナルのテーブルを追加する方法は別の記事を参照ください。
DB追加作成の参考記事 : https://phper.pro/330
【page-test.php】
<?php
//ココにボタン押された時の処理
//例えばデータベースに追加したり削除したりの処理はココに書いとく訳です
// お気に入りボタン押されたら ----------------------------------------
global $favorite;
global $postid;
$favorite = null;
$set_this_ID_favorite = null;
// 呼び出し
$favorite = get_the_author_meta('user_favorite', $userID);
//自身のユーザーID取得
$userID = get_current_user_id();
$postid = $_POST['postid'];
$favoritetype = $_POST['favoritetype'];
// お気に入り削除 ----------------------------------------
if($favoritetype == 'deleteFavorite') {
// 存在する場合DBお気に入りの値を呼び出し
$favorite = explode(",", get_the_author_meta('user_favorite', $userID));
// 既に投稿IDがお気に入りに存在するか判別
if (in_array($postid, $favorite, true)) {
// 配列かどうか判別
if (is_array($favorite)) {
// 1個以上あるなら現在のID以外のものを配列から抜き出す
if (count($favorite) > 0) {
foreach ($favorite as $word) {
if ($word != $postid) {
$set_this_ID_favorites[] = $word;
}
// 現在の投稿ID以外のものを再度配列に入れる
$set_this_ID_favorite = implode(",", $set_this_ID_favorites);
// DBお気に入り内を一度全て削除する
update_user_meta( $userID, 'user_favorite', '');
// 配列に入れておいたものを再度DBお気に入り内へ入れて終了
update_user_meta( $userID, 'user_favorite', $set_this_ID_favorite);
}
// 1個以上ない場合は全削除する為に配列内を空にする
} else {
update_user_meta( $userID, 'user_favorite', '');
}
// 配列ではない場合は全削除
} else {
update_user_meta( $userID, 'user_favorite', '');
}
// DBお気に入り呼び出し
exit;
}
}
$favorite = get_the_author_meta('user_favorite', $userID);
// お気に入り追加 ----------------------------------------
if($favoritetype == 'addFavorite') {
// 存在する場合DBお気に入りの値を呼び出し
$favorite = explode(",", get_the_author_meta('user_favorite', $userID));
// IDの登録が31個以上あったら30個にする
if(count($favorite) >= 31 ){
echo '<script type="text/javascript">alert("お気に入りの追加は30件までとなります");</script>';
//既に31個以上あったら丸める
$set_favorite = array_slice($favorite , 0, 30);
} else {
$set_favorite = $favorite;
}
// 既に投稿IDがお気に入りに存在しない場合は追加
if (in_array($postid, $favorite)) {
header("Location: " .get_permalink());
exit;
} else {
$set_this_ID_favorite = $postid.','.implode(",", $set_favorite);
update_user_meta( $userID, 'user_favorite', $set_this_ID_favorite);
// DBお気に入り呼び出し
exit;
}
}
$favorite = get_the_author_meta('user_favorite', $userID);
?>
DB処理に関しては長くなるのでざっくりとした紹介になります。
まとめ
以上がページ遷移ナシでの「お気に入りボタン」の実装となります。
DBとの連携とか、その辺の理解がないと厳しい部分もあるかもですが、こんな感じで応用していけば、例えば「イイネ」ボタンとかも作れるんじゃないかなと。
使う機会があれば参考にしてみてください。
現場から以上です!
参考 : https://dev-lib.com/php-jquery-send-mail/
5269