Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can i make live Like button with Asp.net MVC 5 and Ajax

I am new at Stackoverflow and this is my first question.

I am making my first blog site, and want a like button, like facebook.

2 problems with my like button.

  1. It wont update like counts in articles with same data-id. I was only avaible to update (this) article-link

  2. When an user likes/dislikes an article, should be able to unlike without refreshing page. It is because it wont check if there is data in database without refreshing page. How can i do that without refresh?

Controller:

        public string LikeThis(int id)
    {
        Article art = DB.Articles.FirstOrDefault(x => x.ID == id);
        if (User.Identity.IsAuthenticated || Session["Username"] != null)
        {
            var Username = User.Identity.Name;
            Member m = DB.Members.FirstOrDefault(x => x.Username == Username);
            art.Likes++;
            Like like = new Like();
            like.ArticleID = id;
            like.UserID = m.ID;
            like.LikedDate = DateTime.Now;
            like.Liked = true;
            DB.Likes.Add(like);
            DB.SaveChanges();

        }

        return art.Likes.ToString();
    }
    public string UnlikeThis(int id)
    {
        Article art = DB.Articles.FirstOrDefault(x => x.ID == id);
        if (User.Identity.IsAuthenticated || Session["Username"] != null)
        {
            var username = User.Identity.Name;
            Member m = DB.Members.FirstOrDefault(x => x.Username == username);
            Like l = DB.Likes.FirstOrDefault(x => x.ArticleID == id && x.UserID == m.ID);
            art.Likes--;
            DB.Likes.Remove(l);
            DB.SaveChanges();

        }
        return art.Likes.ToString();
    }

View:

                        <li>@{ 
                        int userid = Convert.ToInt32(Session["ID"]);

                        if (!User.Identity.IsAuthenticated)
                        {
                            <i class="fa fa-heart-o fa-lg"></i><span>(@art.Likes)</span> 
                        }
                        else if (art.Likes1.Any(x => x.UserID == userid && x.ArticleID == art.ID) || Ajax.ViewBag.Liked == true)
                        {
                            <a href="javascript:void(0)" class="unlike" data-id="@art.ID"><i class="fa fa-heart fa-lg text-danger"></i><span>(@art.Likes)u</span></a>
                        }
                        else
                        {
                            <a href="javascript:void(0)" class="like" data-id="@art.ID"><i class="fa fa-heart-o fa-lg"></i><span>(@art.Likes)l</span></a>
                        }
                        }
                    </li>

Ajax:

        $(document).ready(function () {
        //LIKE
        $("a.like").click(function () {
            var id = $(this).data("id");
            var link = "/Article/LikeThis/" + id;
            var a = $(this);
            $.ajax({
                type: "GET",
                url: link,
                success: function (result) {
                    a.html('<i class="fa fa-heart fa-lg text-danger"></i> (' + result + ')').removeClass("like").addClass("unlike");
                }
            });
        });
        //UNLIKE
        $("a.unlike").click(function () {
            var id = $(this).data("id");
            var link = "/Article/UnlikeThis/" + id;
            var a = $(this);
            $.ajax({
                type: "GET",
                url: link,
                success: function (result) {
                    a.html('<i class="fa fa-heart fa-lg text-danger"></i> (' + result + ')');
                }
            });
        });

    });

I don't hope that i missed anything. Hope u guys can help.

like image 480
Muhaki Avatar asked Nov 03 '25 08:11

Muhaki


1 Answers

The problem is, you registered the click event on the "like" and "unlike" css classes on the document ready event. So it will work for the elements present in DOM at that time. In your success handler of the ajax call, you are resetting the anchor tag html to some new markup and the already registered click event code won't work with this.

What you should do is, use jQuery on event delegation to register your click event. It will work for current and future elements(dynamically injected to DOM).

So change your code from

$("a.like").click(function () {
    //do the ajax call
});

to

$(document).on("click","a.like",function () {
   //do the ajax call
});

and it should work.

Another suggestion is, You can use the same code for both the ajax calls if you keep a data attribute in your markup to determine whether user already liked or not and the target url for each so the markup along with jQuery multiple selectors( both the css classes). Also, you should not try to hardcode the url to your action methods in your js code. Instead you should use the Url.Action helper methods as shown in this post

like image 117
Shyju Avatar answered Nov 05 '25 10:11

Shyju