javascript - AJAX implementation doesn't work properly for "like" button ASP.NET Core 2.1 - Stack Over
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).
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).
Share Improve this question asked yesterday FaridFarid 211 silver badge2 bronze badges New contributor Farid is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 2- 1 append does exactly what you are seeing. It appends the new text after the current one. You should use text() or html(). Then why don't you want to set an individual id for each button? It is just like id='btn' + @item.id and it will be easy to set the individual text. Finally the fact the you see always 1 as LikeCount probably depends on the database code. Check it. – Steve Commented yesterday
- 1 As an aside to the question, .Net Core 2.1 is very outdated now and has been out of support for well over 3 years. .Net9 is available to use, and .Net8 is the latest LTS version. You should really be using one of those, for security, if not performance alone. – Rory McCrossan Commented yesterday
2 Answers
Reset to default 3Your 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.
- Replace your button element with;
<button onclick="IncreaseLike(@item.Id,this)">Like</button>
- Add the new parameter
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>
}
The issue is because append()
is true to its name - it appends the new data to the existing content. To replace the content you can use html()
instead.
However you can both fix the issue and make your code more succinct by using the load()
method to make an AJAX request to the target endpoint and replace the content of the selected element with the response of that request:
function IncreaseLike(id) {
$('.like').load('/Home/AddLike', { id: id });
});
- VMware宣布与Yahoo收购电子邮件和协作软件提供商Zimbra的协议
- 虚拟现实究竟离现实还有多远?
- 一晃三十年 回顾改变世界的那些Windows
- 电脑展趋势分析 移动终端大热DIY被弱化
- 分析:Windows 8平板电脑称雄市场需三大因素
- reactjs - Picture not visible in React - Stack Overflow
- Struggling to Configure Solvers for MINLP Optimization with Pyomo (using NEOS or Local Installation) - Stack Overflow
- node.js - Mongoose schema worked with the main db but not with test db - Stack Overflow
- python - invoke matplotlib toolbar keeping custom views history - Stack Overflow
- reactjs - Flatlist scrolling freeze - Stack Overflow
- javascript - AJAX implementation doesn't work properly for "like" button ASP.NET Core 2.1 - Stack Over
- python - testing the output of seaborn figure level plots - Stack Overflow
- c# - Having trouble getting the correct position to draw my sprite to when rotating it - Stack Overflow
- wordpress - XML Reader Not Found in cPANEL php v8.3 - Stack Overflow
- google cloud platform - Java application unable to find ADC when Workload Identity is enabled on GKE cluster - Stack Overflow
- powerbi - How do I use GenerateSeries with a dynamic end value? - Stack Overflow
- javascript - What are the benefits of Next.js Server Actions, and why should I use them instead of client-side API calls? - Stac