dimanche 20 septembre 2015

Laravel 5: Upvote/Downvote system with AJAX - persisting votes on view and allow to unvote

Sorry for the long title, but I've been at this issue for a while now and I just can't figure it out.

I have an upvote/downvote system in Laravel 5 and using jquery ajax to send request to the controller. I am also using jquery.upvote.js to display the voting buttons.

So far I managed to get the ajax requests sent to the database just fine. However, I have 3 issues that I cannot complete.

  1. Persisting User Voted on View: I cannot persist the user's votes on the posts when the page reloads, say for example I upvoted and downvoted a few posts, then I reloaded the page, my upvotes on the view will disappear as if I haven't voted yet.

  2. Removing Vote if already exists: Say the user already upvoted a post, now he decides to remove his vote by clicking on the same vote button again, this should remove the post, but instead my code is adding a new row in the database with a new upvote.

  3. Remove Vote & Adding New Value: Say the user already upvoted a post, but now he decided that he wants to downvoted. In this case, I should delete the existing vote and add a new one with a new value, correct? or how is this achieved?

I am using resource for my routes

Route::resource('subreddit', 'SubredditController');
Route::resource('posts', 'PostsController');
Route::resource('votes', 'VotesController');

I've been at this for a week, no solution in sight. Please help by providing code example for both php and jquery. And thank you.

Javascript

<script type="text/javascript">
        $(document).ready(function() {
            $('.topic').upvote();

            $('.vote').on('click', function (e) {
                e.preventDefault();
                var data = {value: $(this).data('value'), post_id: $(this).parent().data('post')};

                // var clicked_button = $(this).children();

                $.ajaxSetup({
                    headers: {
                        'X-CSRF-TOKEN': $('[name="_token"]').val()
                    }
                });
                $.ajax({
                    type: "POST",
                    url: 'http://localhost/laravel-5/public/votes',
                    dataType: 'JSON',
                    data: data
                });
            });
        });
    </script>

The relevant part of the View

<div class="col-md-1">
    @if ($voted = in_array($post->id, $votes))
      {!! Form::open(['method' => 'DELETE', 'url' => ['votes', $post->id]]) !!}
    @else
      {!! Form::open(['url' => 'votes', 'class' => 'votes']) !!}
    @endif
       <div class="upvote topic" data-post="{{ $post->id }}">
       <a class="upvote vote {{ $voted ? 'upvote-on' : '' }}" data-value="1"></a>
       <span class="count">0</span>
       <a class="downvote vote {{ $voted ? 'downvote-on' : '' }}" data-value="-1"></a>
       </div>
       {!! Form::close() !!}
     </div>

SubredditController.php where I display a list of posts belonging to a category/subreddit

public function show(Subreddit $subreddit)
    {

        $posts = Subreddit::findOrFail($subreddit->id)->posts()->get();

        $votes = Auth::user()->votes()->get()->toArray();

        //dd($votes);

        return view('subreddit/show')
                ->with('subreddit', $subreddit)
                ->with('posts', $posts)
                ->with('votes', $votes);
    }

VotesController.php store and destroy methods

public function store(Requests\VoteRequest $request)
    {
        // AJAX JSON RESPONSE
        $response = array(
            'status' => 'success',
            'msg' => 'Vote has been added.',
        );
        if(Auth::check()){
            \Log::info(Auth::user());
            Auth::user()->votes()->create($request->all());
        } else {
                return \Response::json('Nope');
        }

        return \Response::json($response);
    }

public function destroy(Requests\VoteRequest $request)
    {
        // AJAX JSON RESPONSE
        $response = array(
            'status' => 'success',
            'msg' => 'Vote has been removed.',
        );

        if(Auth::check()){
            \Log::info(Auth::user());
            Auth::user()->votes()->delete($request->all());
        } else {
            return \Response::json('Nope');
        }

        return \Response::json($response);
    }



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire