I am trying to implement a voting system on answers post just like StackOverflow. I am able to do ajax
request and everything is stored perfectly as the desired way in the database. But I am facing an issue with my View
. In my view, all the answers
‘s Html
is rendered with one for
loop. In this Html
element, I am selecting answer
by div
class called vote
with jQuery
and doing my ajax call and updating my vote count. But the issue is when I am upvoting one answer, Instead of increasing only its vote count, it increases all the answers vote count at the same time.
I think the mistake in selecting all the div
with the vote
class
name. But I am not able to find a way to select them separately to increase my VoteCount
on the selected answers only.
Here is my View
Code.
@model AskMe.Models.ViewModel.QuestionDetailViewModel
@{
ViewBag.Title = "QuestionDetails";
}
<h1>Question Details: </h1>
<h3>@Model.question.Post.Title</h3>
@Html.Raw(Model.question.Post.Content)
<hr />
<h3>Answers:</h3>
<div id="paginationContainer">
@foreach (var answer in Model.question.Answers)
{
<div class="card bg-light m-1">
<div class="card-body">
<h5 class="card-title">Answered by: @answer.Post.CreatedBy.UserName</h5>
@Html.Raw(answer.Post.Content)
</div>
<div class="col vote">
<div>
<button data-vote-id="@answer.Post.PostId" class="nav-link thumbs-up" href=""><i class="fa fa-thumbs-up" aria-hidden="true"></i></button>
</div>
<div class="Count">
@(answer.Post.UpVotes.Count-answer.Post.DownVotes.Count)
</div>
<div>
<button data-vote-id="@answer.Post.PostId" class="nav-link thumbs-down" href=""><i class="fa fa-thumbs-down" aria-hidden="true"></i></button>
</div>
</div>
@Html.ActionLink("View Comments", "Index", "Comments", new { answerId = answer.PostId }, null) |
</div>
}
</div>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h3>Contribute your answer: </h3>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(m => m.AnswerContent, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextAreaFor(m => m.AnswerContent, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
@Html.HiddenFor(m => m.UserId)
@Html.HiddenFor(m => m.QuestionId)
@Html.HiddenFor(m => m.question)
<input type="submit" value="Contribute now" class="btn btn-outline-primary" />
</div>
</div>
</div>
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval");
<script type="text/javascript">
$(document).ready(function () {
tinyMCE.init({
mode: "textareas",
});
$('#paginationContainer').buzinaPagination({
itemsOnPage: 3,
prevnext: true,
prevText: "Previous",
nextText: "Next"
});
$(".vote").on("click", ".thumbs-up", function () {
$.ajax({
url: "/api/votes/upvote/" + $(this).attr("data-vote-id"),
method: "POST",
success: function () {
var countTxt = $(".Count").text();
console.log(countTxt);
var count = parseInt(countTxt);
$(".Count").text(count + 1);
console.log(count);
}
})
})
$(".vote").on("click", ".thumbs-down", function () {
$.ajax({
url: "/api/votes/downvote/" + $(this).attr("data-vote-id"),
method: "POST",
success: function () {
var countTxt = $(".Count").text();
console.log(countTxt);
var count = parseInt(countTxt);
$(".Count").text(count - 1);
console.log(count);
}
})
})
});
</script>
}
and here is my ViewModel
public class QuestionDetailViewModel
{
ApplicationDbContext _context = new ApplicationDbContext();
public virtual Question question { get; set; }
[Display(Name = "Add your answer.")]
public string AnswerContent { get; set; }
public string UserId { get; set; }
public int QuestionId { get; set; }
public int AnswerId { get; set; }
public int VoteCount { get; set; }
}
2
Answers
Thanks, @EugenePodskal to point out my mistake and show me the correct direction for the solution. Here is the solution for question.
Thanks again @EUgenePodskal for your help and time.
You are selecting and setting all
.Count
elements as far as I can see inWhile we should handle only those
.Count
elements that are related to the current answer.It can be done with ancestor + find selector