skip to Main Content

I have a function for adding likes on the page

blade.php

<a href="/article/{{ $article->id }}?type=heart" class="comments-sub-header__item like-button">
<div class="comments-sub-header__item-icon-count">
  {{ $article->like_heart }}
</div>

<a href="/article/{{ $article->id }}?type=finger" class="comments-sub-header__item like-button">
<div class="comments-sub-header__item-icon-count">
  {{ $article->like_finger }}
</div>

js

$(function() {
  $.ajaxSetup({
    headers: {
      'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
    },
  });

  $('.like-button').on('click', function(event) {
    event.preventDefault();

    let href = $(this).attr('href');

    $.ajax({
      url: href,
      type: 'POST',
      success: function() {
        window.location.reload();
      },
    });
  });
});

But when I click on the like to update the data, I reload the page using window.location.reload();

Can this somehow be done without reloading the page?

This is how adding likes is implemented, they are added to cookies and stored for 24 hours

web routes

Route::post('article/{id}', 'AppHttpControllersArticleController@postLike');

Article controller

public function postLike($id, Request $request) {
        $article = Article::find($id);

        if(!$article){
            return abort(404);
        }

        $type = $request->input('type');
      
        if ($article->hasLikedToday($type)) {
            return response()
                ->json([
                    'message' => 'You have already liked the Article '.$article->id.' with '.$type.'.',
                ]);
        }
    
        $cookie = $article->setLikeCookie($type);
      
        $article->increment("like_{$type}");
    
        return response()
            ->json([
                'message' => 'Liked the Article '.$article->id.' with '.$type.'.',
                'cookie_json' => $cookie->getValue(),
            ])
            ->withCookie($cookie);
    }

Article model

public function hasLikedToday(string $type)
    {
        $articleLikesJson = Cookie::get('article_likes', '{}');

        $articleLikes = json_decode($articleLikesJson, true);

        if (!array_key_exists($this->id, $articleLikes)) {
            return false;
        }

        if (!array_key_exists($type, $articleLikes[$this->id])) {
            return false;
        }

        $likeDatetime = Carbon::createFromFormat('Y-m-d H:i:s', $articleLikes[$this->id][$type]);

        return ! $likeDatetime->addDay()->lt(now());
    }

    public function setLikeCookie(string $type)
    {
        $articleLikesJson = Cookie::get('article_likes', '[]');

        $articleLikes = json_decode($articleLikesJson, true);

        $articleLikes[$this->id][$type] = now()->format('Y-m-d H:i:s');

        $articleLikesJson = json_encode($articleLikes);

        return cookie()->forever('article_likes', $articleLikesJson);
    }

4

Answers


  1. $(function() {
      $.ajaxSetup({
        headers: {
          'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
        },
      });
    
      $('.like-button').on('click', function(event) {
        event.preventDefault();
    
        let href = $(this).attr('href');
    
        $.ajax({
          url: href,
          type: 'POST',
          success: function(response) {
            $(this).parent(".comments-sub-header__item-icon-count").html(
    parseInt($(this).parent(".comments-sub-header__item-icon-count").html()) + 1
    )
    // or return like or heart count from server
    $(this).parent(".comments-sub-header__item-icon-count").html(response)
          },
        });
      });
    });
    
    Login or Signup to reply.
  2. This should work for you

    $(function () {
      $.ajaxSetup({
        headers: {
          "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
        },
      });
    
      $(".like-button").on("click", function (event) {
        event.preventDefault();
    
        const likeBtn = $(this);
    
        $.ajax({
          url: likeBtn.attr("href"),
          type: "POST",
          success: function () {
            let currentCount = likeBtn.next().text();
            likeBtn.next().text(parseInt(currentCount) + 1);
          },
        });
      });
    });
    
    
    Login or Signup to reply.
  3. Assuming those DIVs hold the number of hearts, if the response of the target page is the new number of hearts then:

     success: function(data) {
        targetElement.find(".comments-sub-header__item-icon-count").html(data)
     }
    

    elsewhere if you want to add +1 to current number regardless of server response:

     success: function() {
        var current= parseInt(targetElement.find(".comments-sub-header__item-icon-count").html());
        targetElement.find(".comments-sub-header__item-icon-count").html(current+1)
     }
    

    Footnote: as the ajax request is nested inside the click function, the targetElement in my codes is the clicked element. You may get it in defferent ways e.g.

    $('.like-button').on('click', function(event) {
         var targetElement=$(this);
         ....
    }
    
    Login or Signup to reply.
  4. You can simply add the new count to the response from your controller.

    return response()
        ->json([
            'message' => 'Liked the Article '.$article->id.' with '.$type.'.',
            'cookie_json' => $cookie->getValue(),
            'new_count' => $article->{"like_{$type}"},
        ])
        ->withCookie($cookie);
    

    Now you can use the updated count as new_count from the database.

    $.ajax({
        url: href,
        type: 'POST',
        success: function (response) {
            $(this).next().text(response.new_count)
        },
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search