I want to implement "like" button (only like, not dislike) in my project written on ASP.NET Core 2.1 version. This is discount classified site and want visitors to be able to like posts they want. Since I don't have any issue with namespace, I'll only provide action method in the controller from backend, which is as follows:
[HttpPost]
public async Task<IActionResult> AddLike(int Id)
{
AdminPostModel postModel = new AdminPostModel();
postModel.Post = await _offerDbContext.Posts.SingleOrDefaultAsync(x => x.Id == Id);
var UserIP = _accessor.HttpContext?.Connection?.RemoteIpAddress?.ToString();
var Myagent = Request.Headers["User-Agent"].ToString().Substring(0, 40);
string MyVisit = UserIP + " " + Myagent;
postModel.Visitinfos = await _offerDbContext.Visitinfos.ToListAsync();
Visitinfo visitinfo = new Visitinfo();
visitinfo.PostNumber = Id;
visitinfo.Deviceinfo = MyVisit;
if(postModel.Visitinfos.Any(x => x.PostNumber == visitinfo.PostNumber && x.Deviceinfo == visitinfo.Deviceinfo))
{
ViewBag.Message = "Eyni elanı bir dəfədən çox bəyənə bilməzsiniz";
return Json(postModel.Post.LikeCount);
}
else
{
_offerDbContext.Visitinfos.Add(visitinfo);
postModel.Post.LikeCount++;
await _offerDbContext.SaveChangesAsync();
return Json(postModel.Post.LikeCount);
}
}
Please, don't confuse yourself with user IP or user-agent details which is not related to my problem. I returned JSON with the result of number of likes (LikeCount) which is the property of Post model, and accessed it through view model in this action. Here is posts parts of cshtml view:
@foreach (Post item in Model)
{
<div class="postcontent">
<div class="row">
<div class="col-lg-12 col-md-12">
<div class="uppart">
<h6>@item.Title</h6>
</div>
<div class="imgframe">
@if (item.URL != null)
{
<a href="@item.URL" target="_blank"> <img class="postimg" src="~/images/@item.Image"></a>
}
else
{
<a asp-action="Detailed" asp-controller="Detailed" asp-route-id="@item.Id" target="_blank"><img class="postimg" src="~/images/@item.Image"></a>
}
</div>
<div class="posttext">
<p>
@item.Description
</p>
<p class="formore">
<a href="@item.URL" target="_blank">ƏTRAFLI</a>
</p>
</div>
<div class="dates">
<p class="postdate">Tarix: @item.CreatedDate.ToString("dd/MM/yyyy")</p>
@if (item.ExpirationDate.ToString("dd/MM/yyyy") == "01.01.2021" || item.ExpirationDate.ToString("dd/MM/yyyy") == "01/01/2019")
{
<p class="expdate">Bitme tarix: Naməlum</p>
}
else
{
<p class="expdate">Bitme tarix: @item.ExpirationDate.ToString("dd/MM/yyyy") </p>
}
**<button onclick="IncreaseLike(@item.Id)">Like</button>
<p class="like"></p>**
</div>
</div>
</div>
As you see, within button tag, I called IncreaseLike() function for Post Id, which is used in Javascript part like below:
@section Script{
<script>
function IncreaseLike(id) {
$.ajax({
url: "/Home/AddLike",
type: "POST",
data: { id: id },
}).done(function (result) {
$(".like").append(result);
}
)
};
</script>
}
The aim of using AJAX is to interrupt page loading after clicking on "like" button. But when running application, after clicking on "like" button it adds new 1 next to previous 1 instead of updating figure on its place. And it applies it for all posts of the page instead of only particular clicked one. Maybe it's because I append it to a class (.like), but I don't want to define different Id for each post in the page, how can I implement ajax so that it would append to only chosen post, and only one time by increasing like number, not to place new next to the number? There is no issue with database as it works without using ajax and using asp-action and asp-controller tag helpers, but this makes the page load in each click. Please, read my code carefully, and assist in finding issue which probably comes from JS part (AJAX).
Your jquery code should use .html()
which replaces the HTML content of the target element.
@section Script{
<script>
function IncreaseLike(id) {
$.ajax({
url: "/Home/AddLike",
type: "POST",
data: { id: id },
}).done(function (result) {
$(".like").html(result);
})
};
</script>
}
Since you don't want to add data-id for each post in the page, follow the steps below to replace the nearest post from the button you clicked.
<button onclick="IncreaseLike(@item.Id,this)">Like</button>
button
to your function and use .parent()
to replace the nearest .like
.@section Script{
<script>
function IncreaseLike(id, button) {
$.ajax({
url: "/Home/AddLike",
type: "POST",
data: { id: id },
}).done(function (result) {
$(button).parent().find(".like").html(result);
})
};
</script>
}