如何在 Laravel 中使用 jQuery Ajax 创建喜欢/不喜欢功能?

How to create a Like/Dislike feature using jQuery Ajax in Laravel?

提问人:Hilmi Hidayat 提问时间:11/18/2023 更新时间:11/18/2023 访问量:43

问:

我在Laravel中使用jQuery Ajax创建了一个喜欢/不喜欢功能。从功能上讲,“喜欢/不喜欢”操作运行正常。问题是,当我在 property-id = 6 上单击 Like 时,添加到喜欢的类中的是 property-id = 5。假设,如果我在 property-id = 6 上单击 Like,那么添加到喜欢的类中的内容是 property-id = 6。它应该是,如果我为 property-id = 6 单击 Unline,则必须删除 property-id = 6 上的喜欢的类。如何解决这个问题?下面,我将包含我创建的代码。

叶片

<div class="property-listing">
    <div class="row g-2">
        @foreach ($properties as $property)
        <div class="col-lg-6 col-12 mb-3">
            <div class="card property-item shadow-sm p-2 pb-0 h-100">
                <div class="position-absolute top-0 start-0 z-index-1 m-4">
                    <div class="badge text-bg-light">
                        From ${{ $property->monthly_price }}/month
                    </div>
                </div>
                <div class="position-absolute top-0 end-0 z-index-1 m-4">
                    <button class="btn favorite-btn rounded-circle {{ $property->isLiked() ? 'liked' : '' }}" aria-label="like" type="button" data-property-id="{{ $property->id }}" id="like-btn">
                    <i class="fa-solid fa-heart fs-3"></i>
                    </button>
                </div>
                <div class="rounded-2 overflow-hidden">
                    <div class="property-galleries mb-0">
                        @foreach ($property->getMedia('property images') as $media)
                        <div><img data-src="{{ $media->getFullUrl() }}" class="lazy" alt="{{ $property->title }}"></div>
                        @endforeach
                    </div>
                </div>
                <div class="position-relative">
                    <div class="card-body px-1 pb-0">
                        <h2 class="card-title fw-bold">
                            <a href="{{ route('front.property-detail', $property->slug) }}">
                            <span class="fw-bold">
                            {{ $property->title }}
                            </span>
                            </a>
                        </h2>
                        <div class="meta">
                            <ul>
                                <li>
                                    {{ $property->district->name }}
                                </li>
                                <li>
                                    {{ $property->specification }}
                                </li>
                                <li>
                                    {{ $property->size }} Sq Ft
                                </li>
                            </ul>
                        </div>
                    </div>
                    <div class="card-footer border-0 bg-transparent px-1 pt-2 d-flex mx-auto">
                        <div class="d-flex flex-column">
                            <span class="text-muted small">
                            Starting at
                            </span>
                            <span class="fw-normal small">
                            ${{ $property->nightly_price }}/night
                            </span>
                        </div>
                        <a href="{{ route('front.property-detail',$property->slug) }}" class="btn btn-sm check-btn mb-0 mt-3 ms-auto stretched-link">Check Availability</a>    
                    </div>
                </div>
            </div>
        </div>
        @endforeach
    </div>
</div>

阿贾克斯

$(document).on('click', '#like-btn', function(e) {
    e.preventDefault();
    var id = $(this).data('property-id');
    var url = "{{ route('like', ':id') }}";
    url = url.replace(':id', id);
    $.ajax({
        url: url,
        method: 'POST',
        data: {
            _token: '{{ csrf_token() }}'
        },
        success: function(response) {
            if (response.message == 'liked') {
                //add class liked to #like-btn button with data-id = id
                $('#like-btn').addClass('liked');
            }
    
            if (response.message == 'unliked') {
                //remove class liked
                $('#like-btn').removeClass('liked');
            }
        }
    });
});

控制器

public function like(Property $property)
{
    try {
        if ($property->isLiked()) {
            $property->removeLike();
            return response()->json(['message' => 'unliked'], 200);
        }

        $property->likes()->create([
            'user_id' => auth()->id(),
            'ip' => request()->ip(),
            'user_agent' => request()->userAgent(),
        ]);
        
        return response()->json(['message' => 'liked'], 200);

    } catch (\Exception $e) {
        return response()->json(['message' => $e->getMessage()], 500);
    }
}
javascript php jquery laravel

评论

5赞 miken32 11/18/2023
id属性在文档中必须是唯一的。
1赞 Tim Lewis 11/18/2023
@foreach(...) [...] id="like-btn" [...] @endforeach->那是你的问题。由于 your 不是唯一的,因此当您单击其中一个时,它只会触发其中一个上的逻辑,而不一定是您单击的那个。您可能应该使用类,例如 ,然后调整逻辑以针对正确的元素。id="like-btn"class="like-btn"on('click', '.like-btn', ...)
0赞 Hilmi Hidayat 11/18/2023
解决。谢谢@TimLewis

答:

2赞 Hilmi Hidayat 11/18/2023 #1

解决。我像这样更改了 Ajax 脚本。

阿贾克斯

$(document).on('click', '.favorite-btn', function(e) {
    e.preventDefault();
    var id = $(this).data('property-id');
    var url = "{{ route('like', ':id') }}";
    url = url.replace(':id', id);
    $.ajax({
        url: url,
        method: 'POST',
        data: {
            _token: '{{ csrf_token() }}'
        },
        success: function(response) {
            if (response.message == 'liked') {
                $('.favorite-btn[data-property-id=' + id + ']').addClass('liked');
            }
    
            if (response.message == 'unliked') {
                $('.favorite-btn[data-property-id=' + id + ']').removeClass('liked');
            }
        },
        error: function(error) {
            if (error.status == 401) {
                window.location.href = "{{ route('login') }}";
            }
            console.log(error);
        }
    });
});

评论

0赞 Jacob 11/19/2023
那么请接受你的回答。