1

0 I followed a solution on how to get Django Like and Unlike button not to reload the page on click. The solution i found works but only with TEXT toggle (Like and Unlike) and i want an Icon Toggle (Like and Unlike Icon).

I am new to Django Backend and Ajax, i will be happy if someone can help on how to deal with this. Thanks in Advance.

$( document ).ready(function() {

  $('.like-form').submit(function(e){
        e.preventDefault()

        const post_id = $(this).attr('id')

        const likeText = $(`.like-btn${post_id}`).text()
        const trim = $.trim(likeText)

        const url = $(this).attr('action')

        let res;
        const likes = $(`.like-count${post_id}`).text()
        const trimCount = parseInt(likes)

        $.ajax({
            type: 'POST',
            url: url,
            data: {
                'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val(),
                'post_id':post_id,
            },
            success: function(response) {
                if(trim === 'Unlike') {
                    $(`.like-btn${post_id}`).text('Like')
                    res = trimCount - 1
                } else {
                    $(`.like-btn${post_id}`).text('Unlike')
                    res = trimCount + 1
                }

                $(`.like-count${post_id}`).text(res)
            },
            error: function(response) {
                console.log('error', response)
            }
        })

    });
});
<!-- Like Button -->
<li class="list-inline-item">
  <form action="{% url 'posts:like-post-view' %}"  method="POST" class='like-form' id='{{obj.id}}'>
 {% csrf_token %}
  <input type="hidden" name="post_id" value={{obj.id}}>
                                            
  <button type="submit" class="btn btn-link g-color-gray-dark-v5 g-color-red--hover text-red p-0 border-0 btn-outline-light like-btn{{obj.id}}">
{% if user not in obj.liked.all %}
Like
    <i class="align-middle mr-1 icon-heart u-line-icon-pro g-font-size-25"></i>
{% else %}
Unlike
    <i class="align-middle mr-1 icon-like u-line-icon-pro g-font-size-25"></i>
{% endif %}
  </button>
  <span class="g-color-gray-dark-v5 g-font-size-15 like-count{{obj.id}}"> {{obj.num_likes}}</span>
  </form>
</li>
<!-- End Like Button -->
MoAlanteh
  • 23
  • 5
  • Hi why not simply do like this : `$(".like-btn"+post_id).html('Like')` and same for other button as well. – Swati Nov 30 '20 at 04:01
  • @Swati i tried that yesterday but didn't work correctly. The icon toggles only on the first click and never unless you reload the page. The only thing working correctly is the text toggling (LIKE and UNLIKE) But the icon is really not . – MoAlanteh Nov 30 '20 at 05:54

1 Answers1

1

You can append icons as well inside your success function with text . Also , put like and unlike inside span so that it would be easy to change value .

Demo Code :

$('.like-form').submit(function(e) {
  e.preventDefault()

  const post_id = $(this).attr('id')

 const likeText = $(".like-btn"+post_id).find("i").hasClass("fa-heart-o") ? "Unlike":"Like"//check for class and if true then set value as unlike or like..
  const trim = $.trim(likeText)

  const url = $(this).attr('action')

  let res;
  const likes = $(`.like-count${post_id}`).text()
  const trimCount = parseInt(likes)

  /*  $.ajax({
      type: 'POST',
      url: url,
      data: {
        'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val(),
        'post_id': post_id,
      },
      success: function(response) {*/
  if (trim === 'Unlike') {
  //use .html to add htmls codes
    $(`.like-btn${post_id}`).html('<i class="fa fa-heart" aria-hidden="true"></i>')
    res = trimCount - 1
  } else {
    $(`.like-btn${post_id}`).html('<i class="fa fa-heart-o" aria-hidden="true"></i>')
    res = trimCount + 1
  }

  $(`.like-count${post_id}`).text(res)
  /*  },
    error: function(response) {
      console.log('error', response)
    }
  })*/

});
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form action="{% url 'posts:like-post-view' %}" method="POST" class='like-form' id='1'>

  <input type="hidden" name="post_id" value=1>

  <button type="submit" class="btn btn-link g-color-gray-dark-v5 g-color-red--hover text-red p-0 border-0 btn-outline-light like-btn1">
  <!--put texxt inside span-->
 <i class="fa fa-heart" aria-hidden="true"></i>
  </button>
  <span class="g-color-gray-dark-v5 g-font-size-15 like-count1">12</span>
</form>
<form action="{% url 'posts:like-post-view' %}" method="POST" class='like-form' id='2'>

  <input type="hidden" name="post_id" value=2>

  <button type="submit" class="btn btn-link g-color-gray-dark-v5 g-color-red--hover text-red p-0 border-0 btn-outline-light like-btn2">
 <i class="fa fa-heart-o" aria-hidden="true"></i>
  </button>
  <span class="g-color-gray-dark-v5 g-font-size-15 like-count2">5</span>
</form>
Swati
  • 28,069
  • 4
  • 21
  • 41
  • Thank you so so much your solution works perfectly. How about if i only want to display the icon only no text? – MoAlanteh Nov 30 '20 at 16:09
  • Hi , you can check the class of `i` tag and depending on that change your icon . So, according to my code you need to change `const likeText = $(".like-btn"+post_id).find("i").hasClass("fa-heart-o") ? "Like":"Unlike"` – Swati Dec 01 '20 at 04:16
  • Thank you again @Swati . So i just have to change this line of code ( const likeText = $(".like-btn"+post_id).find("i").hasClass("fa-heart-o") ) and remove the span tag with the text to achieve the results am looking for? Where does ("Like":"Unlike") goes? Can you maybe update your demo answer with this solution please for better understanding, Thanks for your time and support. – MoAlanteh Dec 01 '20 at 07:32
  • Hi, i have updated my answer have a look :) – Swati Dec 01 '20 at 13:07
  • Thank you again @Swati ..... so now i have to use two forms one for the like button and another for the Unlike... Correct? – MoAlanteh Dec 01 '20 at 13:27
  • Nah .. that just for demo . Use only one form to like/unlike – Swati Dec 01 '20 at 13:30
  • Thx a lot @Swati, it works like a charm, you are super awesome. Thx u so so much. I don’t want to bother you but i have a similar issue with the comment form, when i submit the form the page reloads or jump to the top of the page. I will be more than happy if you have time to check it out. ( https://stackoverflow.com/questions/65078310/django-ajax-and-js-how-to-prevent-page-reloads-and-jump-ups-to-the-top-of-the/65078991?noredirect=1#comment115053891_65078991 ) I think the same method here can be implemented to stop to reload and submit the form. Thanks once again :) – MoAlanteh Dec 01 '20 at 13:49