🚀
Laravel + jQueryでサイト内お気に入り機能を実装してみた
概要
今回はAjax
を利用したサイト内お気に入り機能の実装方法を紹介します
お気に入り登録画面作成
index.blade.php
<meta name="csrf-token" content="{{ csrf_token() }}">
<li>
<div class="mb-3">
<label class="form-label">
<span class="icon_left">
<i class="fas fa-search"></i>
<a data-toggle="collapse" href="#collapseFavorite"><small>お気に入りから検索</small></a>
</span>
</label>
<label class="collapse" id="collapseFavorite">
<input type="checkbox" name="is_search_favorite"
value="1" {{$query->get('is_search_favorite') == 1 ? 'checked':null}}>
</label>
</div>
</li>
<div class="row">
<div class="col-12 col-sm-6 col-md-6 col-lg-6 col-xl-6 mb-3">
@php
if (\Illuminate\Support\Facades\Session::has('favorite')) {
$itemIds = array_filter(!is_null((\Illuminate\Support\Facades\Session::get('favorite'))) ? explode(',', (\Illuminate\Support\Facades\Session::get('favorite'))) : []);
}
else{
$itemIds = [];
}
@endphp
<button type="button"
class="btn-favorite-icon btn btn-lg border border-secondary mb-3 ml-2 btn-block"
style="background-color: #fefcf6" id="favorite_icon"
data-id="{{$item->id}}">
@if(!empty($itemIds) && in_array($item->id,$itemIds))
<i class="fas fa-star icon-color" id="favorite-icon"></i>
@else
<i class="far fa-star" id="favorite-icon"></i>
@endif
<small>お気に入り</small>
</button>
</div>
</div>
解説
- POSTパラメーターとしてCSRFトークンを確認するためにトークンを保存します
<meta name="csrf-token" content="{{ csrf_token() }}">
-
セッションから現在お気に入りに登録している商品IDを取得します
-
array_filter
:配列内に空文字列が入る場合等を考慮して削除します -
explode
: 配列を文字列に変換したものをセッションに保存しているので配列に変換する
@php
if (\Illuminate\Support\Facades\Session::has('favorite')) {
$itemIds = array_filter(!is_null((\Illuminate\Support\Facades\Session::get('favorite'))) ? explode(',', (\Illuminate\Support\Facades\Session::get('favorite'))) : []);
}
else{
$itemIds = [];
}
@endphp
- セッションにお気に入り情報が存在していて、商品IDが含まれている場合は、アイコンを変更します
@if(!empty($itemIds) && in_array($item->id,$itemIds))
<i class="fas fa-star icon-color" id="favorite-icon"></i>
@else
<i class="far fa-star" id="favorite-icon"></i>
@endif
ルーティングを定義します
<?php
use Illuminate\Support\Facades\Route;
Route::post('/set_session/favorite', 'IndexControll@setSession');
お気に入りボタンをクリックした後の処理を追加
index.js
$('[id=favorite_icon]').on('click', function () {
const id = $(this).data('id');
const icon = $(this).children('i');
$.ajaxSetup({
headers: {
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
},
});
$.ajax(
{
url: "/set_session/favorite",
type: "POST",
data: {
"item_id": id
},
dataType: 'json',
complete: function (res) {
if (res.responseJSON.status) {
const ids = (res.responseJSON.ids).split(',');
if (jQuery.inArray(String(id), ids) !== -1) {
icon.removeClass('far fa-star');
icon.addClass('fas fa-star icon-color');
} else {
icon.removeClass('fas fa-star icon-color');
icon.addClass('far fa-star');
}
} else {
alert('予期せぬエラーが発生しました。');
}
}
}
)
});
## 解説
- 同じIDを複数持つ要素全てにクリックイベントを発火させます
$('[id=favorite_icon]').on('click', function () {}
``data-id="{{$item->id}}"で指定している商品IDを
data`属性から取得します
const id = $(this).data('id');
- CSRFトークンをヘッダー情報に設定します
$.ajaxSetup({
headers: {
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("conte
https://www.flatflag.nir87.com/split-2178
```js
const ids = (res.responseJSON.ids).split(',');
-
jQuery.inArray
で配列内にアイテムIDが存在する場合にクラス名を変更します -
inArray
の戻り値が見つからない場合は-1
を返す仕様上以下条件で分岐します -
String(id)
で配列内の要素がString
型のため型を合わせるためにINT型
から変換します
if (jQuery.inArray(String(id), ids) !== -1) {
icon.removeClass('far fa-star');
icon.addClass('fas fa-star icon-color');
} else {
icon.removeClass('fas fa-star icon-color');
icon.addClass('far fa-star');
}
お気に入り登録のロジックを構築
IndexControll.php
<?php
namespace App\Http\Controllers;
class IndexController extends Controller
{
/**
* お気に入りをセッションに保持する
* @param Request $request
* @return JsonResponse
*/
public function setSession(Request $request): JsonResponse
{
try {
$itemId = $request->input('item_id');
$offerIds = null;
// セッションに存在する場合は保持した値を配列に変換する
if (Session::has('favorite')) {
$itemIds = !is_null(Session::get('favorite')) ? explode(',', Session::get('favorite')) : [];
}
// お気に入りに1件もなければとりあえず保存する
if (empty($itemIds)) {
$itemIds[] = $itemId;
}
// お気に入り一覧に存在しない場合は追加・存在する場合は削除
if (!in_array($itemId, $itemIds)) {
$itemIds[] = $itemId;
} else {
$index = array_search($itemId, $itemIds);
unset($itemIds[$index]);
}
// セッション更新
Session::forget('favorite');
Session::put(['favorite' => implode(',', $itemIds)]);
return response()->json([
'status' => true,
'ids' => Session::get('favorite'),
'id' => $itemId,
'message' => 'success',
]);
} catch (\Exception $e) {
return response()->json([
'status' => false,
'message' => $e->getMessage(),
]);
}
}
}
以下のような動きになります
またセッションに保存しているのでページを再レンダリングした場合も保持できます
まとめ
今回はサイト内お気に入り機能についてまとめました
いいねしていただけると記事執筆の励みになりますので、参考になったと思った方は是非よろしくお願いします!
Discussion