Calling JQuery Ajax Functions in Foreach loop - Need assitance - javascript

I am currently studying programming and trying to build a website with .Net Core.
I have the following issue. I am not familiar with JavaScript that much and I have two JQuery/AJAX functions on my Index page. One of the function is for the posts likes/dislikes and the other for posts comments.
My ViewModel contains a collection of Posts:
public IEnumerable<IndexPostViewModel> Posts { get; set; }
public int PagesCount { get; set; }
public int CurrentPage { get; set; }
Into my view I am looping through each Post and in it, through each Comment.
#foreach (var post in Model.Posts)
{
<div class="post-content">
<img src=#post.ImageUrl width="500" height="500" alt="post-image" class="img-responsive post-image" />
<div class="post-container">
<img src="http://placehold.it/300x300" alt="user" class="profile-photo-md pull-left" />
<div class="post-detail">
<div class="user-info">
<h5>#post.User.UserName <span class="following">following</span></h5>
<p class="text-muted">Post published at: #post.CreatedOn</p>
</div>
<div class="reaction">
<a class="btn text-green" href="#" method="post" onclick="sendVote(#post.Id, true)"><div class="icon ion-thumbsup" id="upVotes">#post.UpVotes</div></a>
<a class="btn text-red" href="#" method="post" onclick="sendVote(#post.Id, false)"><div class="fa fa-thumbs-down" id="downVotes">#post.DownVotes</div></a>
</div>
<div class="line-divider"></div>
<div class="post-text">
<p>#post.Text</p>
</div>
<div class="line-divider"></div>
#foreach (var comment in post.Comments)
{
<div class="post-comment">
<img src="http://placehold.it/300x300" alt="" class="profile-photo-sm" />
<p>#post.User.Email<i></i> #comment.Text</p>
</div>
}
<form id="myForm" asp-controller="Comment" asp-action="Create" method="post">
<input type="hidden" name="PostId" id="postId" value="#post.Id" />
<textarea name="text"></textarea>
<input type="submit" value="Submit Comment" />
</form>
</div>
</div>
</div>
And these are the functions in the Scripts section:
#section Scripts {
function sendVote(postId, isUpVote) {
var json = { postId: postId, isUpVote: isUpVote };
$.ajax({
url: "/api/votes",
type: "POST",
data: JSON.stringify(json),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
$("#upVotes").html(data.upVotes);
$("#downVotes").html(data.downVotes);
}
});
}
// wait for the DOM to be loaded
$(document).ready(function () {
// bind 'myForm' and provide a simple callback function
$('#myForm').each.ajaxForm(function () {
alert("You have just posted a comment");
document.location.reload(true);
});
});
</script>
}
My issue is that both functions are working correctly only for the first post. Can you please assist on how to modify the functions to be applied for each element in the loop?
Thanks in advance.

the problem is simple.
your selector and ids are not unique
id can only be defined for one element, same id on multiple/same elements will cause this issue.
the link tag has a common id for all records, it needs to be unique.
make the ids unique , i added #post.Id with ids, this will make each unique
<div class="reaction">
<a class="btn text-green" href="#" method="post" onclick="sendVote(#post.Id, true)"><div class="icon ion-thumbsup" id="upVotes_#post.Id">#post.UpVotes</div></a>
<a class="btn text-red" href="#" method="post" onclick="sendVote(#post.Id, false)"><div class="fa fa-thumbs-down" id="downVotes_#post.Id">#post.DownVotes</div></a>
</div>
and in you js change the selector by adding id
function sendVote(postId, isUpVote) {
var json = { postId: postId, isUpVote: isUpVote };
$.ajax({
url: "/api/votes",
type: "POST",
data: JSON.stringify(json),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
$("#upVotes_"+postId).html(data.upVotes); // change here
$("#downVotes_"+postId).html(data.downVotes);
}
});
}
and also for myform do the same, you dont need id for form, but if you want just add the #post.Id to id,
<form id="myForm" class="myform" asp-controller="Comment" asp-action="Create" method="post">
<input type="hidden" name="PostId" id="postId" value="#post.Id" />
<textarea name="text"></textarea>
<input type="submit" value="Submit Comment" />
</form>
and in event change id to class to make it dynamic,
$('.myForm').each.ajaxForm(function () {
// $(this) will give you access to the specific form only
alert("You have just posted a comment");
document.location.reload(true);
});

Related

jquery not sending data to Post Action Asp.Net Core MVC

I am trying to save a ViewModel object from a partial view in a modal, and I get a 404 error when I try to post it. The url is being called, but the ViewModel data isn't being sent. I have been reading similar questions on here and on MSN for hours and nothing I've tried fixes the problem. I took out the repetitive days of the week code for brevity, but I can
add them back in if anyone wants a complete working example. Here is the code
EmployeeViewModel
public class EmployeeViewModel
{
public bool Monday { get; set; } = false;
//...bool properties for Tuesday through Sunday
public Employee Employee { get; set; }
}
Employee/ _AddEmployeeModalPartial
#model JSarad_C868_Capstone.ViewModels.EmployeeViewModel
#Html.AntiForgeryToken()
<div class="modal modal-fade" id="addEmployee">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="addEmpoyeeLabel">Add Employee</h4>
<button type=button class="close" data-bs-dismiss="modal">
<span>x</span>
</button>
</div>
<div class="modal-body">
<form action="Add">
<div class="form-group">
<input asp-for="Employee.Id" class="form-control" />
<input asp-for="Employee.Availability" class="form-control" />
<label asp-for="Employee.Role"></label>
<select asp-for="Employee.Role" class="form-control">
<option value="Bartender">Bartender</option>
<option value="Server">Server</option>
</select>
<span asp-validation-for="Employee.Role" class="text-danger"></span>
</div>
#*<div class="mb-3">*#
<div class="form-group">
<label asp-for="Employee.Name"></label>
<input asp-for="Employee.Name" class="form-control" />
<span asp-validation-for="Employee.Name" class="text-danger"></span>
</div>
#* <div class="mb-3">*#
<div class="form-group">
<label asp-for="Employee.Phone"></label>
<input asp-for="Employee.Phone" class="form-control" />
<span asp-validation-for="Employee.Phone" class="text-danger">
</span>
</div>
#*<div class="mb-3">*#
<div class="form-group">
<label asp-for="Employee.Email"></label>
<input asp-for="Employee.Email" class="form-control" />
<span asp-validation-for="Employee.Email" class="text-danger">
</span>
</div>
#*<div class="mb-3">*#
<div class="form-group">
<label asp-for="Employee.Address"></label>
<input asp-for="Employee.Address" class="form-control" />
<span asp-validation-for="Employee.Address" class="text-danger">
</span>
</div>
#* <div class="mb-3">*#
<div class="form-group">
<label>Availabiliy</label>
</div>
<div class="row pb-4">
<div class="col">
<div class="form-check">
<input asp-for="Monday" class="form-check-input"
type="checkbox" />
<label asp-for="Monday" class="form-check-label"></label>
</div>
<!--...//form check boxes for Tuesday trough Sunday -->
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary"
data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary"
data-bs-save="modal">Save</button>
</div>
</div>
</div>
</div>
EmployeeController.cs
[HttpGet]
public IActionResult Add()
{
EmployeeViewModel viewModel = new EmployeeViewModel();
return PartialView("_AddEmployeeModalPartial", viewModel); ;
}
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Add(EmployeeViewModel viewModel) //code never reaches this Action
{
viewModel.Employee.Availability = ConvertDaysToChar(viewModel.Employee.Availability)
if (ModelState.IsValid)
{
_db.Employees.Add(viewModel.Employee);
_db.SaveChanges();
return RedirectToAction("Index");
}
else
{
return PartialView("_AddEmployeeModelPartial", viewModel);
}
}
site.js
$(function () {
var PlaceHolderElement = $('#PlaceHolderHere');
$('button[data-bs-toggle="ajax-modal"]').click(function (event) {
/* event.preventDefault();*/
var url = $(this).data('url');
console.log(url)
$.get(url).done(function (data) {
PlaceHolderElement.html(data);
PlaceHolderElement.find('.modal').modal('show');
})
})
PlaceHolderElement.on('click', '[data-bs-save="modal"]', function (event) {
event.preventDefault();
var form = $(this).parents('.modal').find('form');
var actionUrl = form.attr('action');
console.log(actionUrl);
var sendViewModel = form.serialize();
console.log(sendViewModel);
//$.post(actionUrl, sendViewModel).done(function (data) {
// PlaceHolderElement.find('.modal').modal('hide');
/*above is the code from a tutorial for modals. It also doesn't send the object to
post action*/
$.ajax({
type: 'POST',
url: actionUrl,
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify(sendViewModel),
success: function (result) {
console.log('Data received: ');
console.log(result);
}
})
})
})
When I click the save button on the model, the console.log(sendViewModel) returns the correct Serialization with all of the properties and their correct names. And the properties change correctly when there is input.
Employee.Id=&Employee.Availability=&Employee.Role=Bartender&Employee.Name=&Employee.Phone=&Employee.Email=&Employee.Address=&Monday=false&Tuesday=false&Wednesday=false&Thursday=false&Friday=false&Saturday=false&Sunday=false
But I get an error "Failed to load resource: the server responded with a status of 404 ()"
and when I check it the page says "No webpage was found for the web address: https://localhost:44313/Add HTTP ERROR 404" as if it's trying to get a post. It is also missing the controller, but if I change my form action to "Employee/Add" in the _Partial view it still doesn't send the data along with the url, which is causing an entirely different problem. I would greatly appreciate any help or guess or input of any kind. I'm about five seconds away from throwing my laptop out the window on this one. Thanks.
1.Remove the #Html.AntiForgeryToken() inside your form,like below:
<form action="Add" >
#Html.AntiForgeryToken()
....
Then after you serialize the form you can get the AntiForgeryToken, like below:
Because when you don't add #Html.AntiForgeryToken()inside form, after you serialize the form you don't get the AntiForgeryToken, like below:
Besides, if you use <form asp-action="Add" > In ASP.Net Core anti forgery token is automatically added to forms, so you don't need to add #Html.AntiForgeryToken(),you can find in the below :
2.change your ajax like below:
$.ajax({
type: 'POST',
url:'/Employee/Add',
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
data: sendViewModel,
success: function (result) {
console.log('Data received: ');
console.log(result);
}
})
result:
First, I had to change the form action from "Add" to "Employee/Add". ThenI had to remove the antiforgery token from my post action. The first code that is commented out actually works fine otherwise. In my defense I did remove the antiforgery token when I had the wrong URL, but I forgot to retest that when I had the correct one.

How to set two values to one html button

I'm working on a page where i'm rendering data from an api, where i make dynamic profile cards. And on clicking the button inside the card i'm calling an api through ajax. my problem is i need two values to pass to req.body to make the ajax success. I mananged the api call using one data using this code,
<div class="container" id="bb1">
<% locals.posts.rows.forEach(function (patient) { %>
<div class="patient-data">
<div >
<div style="padding-left: 100px"> <img src="<%= patient.dp %>" style="width: 45%;"> </div>
<br>
<div style="text-align: center;">
<h5> P.ID : <%= patient.p_id %></h5>
<p> Name : <%= patient.patient_name %></p>
</div>
<div style="padding-left: 110px;margin-bottom:20px ;">
<button type = "button" id="<%= patient.p_id %>" onclick="approve(this.id)" type="button" class="btn btn-info btn-sm" id="btn-success" style="background-color: #D1B147;"> View</button> </a></div>
</div>
</div>
<% }); %>
</div>
then inside my script;
<script type="text/javascript">
function approve(id) {
var p_id = id;
console.log(p_id);
var data = {};
data.p_id = p_id;
$.ajax({
type: 'POST',
data: JSON.stringify(data),
contentType: 'application/json',
dataType: 'json',
url: "http://localhost:5000/mData",
success: function(data) {
console.log(data);
localStorage.setItem('myData', JSON.stringify(data));
window.location.href = 'mastersessionhistory';
},
error: function(){
alert("Error")
console.log('error occured')
}
})
}
</script>
using this i was able to hit api and return values. i needed only the p_id to hit api. But now i have new key m_id to so my req.body should be {p_id,m_id}. How to include m_id on that bitton click so that i can call the api.
can i use this
<button type = "button" id="<%= patient.p_id, patient.m_id%>" onclick="approve(this.id)" type="button" class="btn btn-info btn-sm" id="btn-success" style="background-color: #D1B147;"> View</button> </a></div>

Controller method is not detecting any parameter

I'am trying to send an id in my url but my controller doesn't get that value
$("#ChangeSlideForm").on("submit", function(){
$.ajax({
type: "POST",
url: base_url + "Visualiser/ChangeSlide/21",
success: function (response) {
alert(response);
// $("#deleteConfirm").modal('hide');
// jQuery(function RefreshPageAdd($){
// $('#deleteConfirm').on('hidden.bs.modal', function (e) {
// location.reload();
// });
// });
}
});
});
My View
<div id="bodyChange" class="modal-body">
<form id = "ChangeSlideForm" action="<?php echo base_url() ?>Visualiser/ChangeSlide" enctype="multipart/form-data" method="post" accept-charset="utf-8">
<label class="btnSlide btn btn-outline-success">
Zip <input class="file" name="file[]" type="file" hidden>
</label>
<label class="btnSlide btn btn-outline-success">
Csv <input class="file" name ="file[]" type="file" hidden>
</label>
</div>
<div class="modal-footer">
<div class="col-md-12 text-center">
<button type="submit" class="btn btn-primary col-md-6">Ajouter</button>
</div>
</form>
My controller header :
public function ChangeSlide($id){
print_r($id);
}
When I a put the id in the url directly then the parameter is accessible otherwise when I pass with ajax, It doesn't detect the parameter.
Try this:-
The HTML
<form id="ChangeSlideForm" action="<?php echo base_url() ?>Visualiser/ChangeSlide/21" enctype="multipart/form-data" method="post" accept-charset="utf-8">
<div id="bodyChange" class="modal-body">
<label class="btnSlide btn btn-outline-success"> Zip
<input class="file" name="file[]" type="file" hidden>
</label>
<label class="btnSlide btn btn-outline-success"> Csv
<input class="file" name="file[]" type="file" hidden>
</label>
</div>
<div class="modal-footer">
<div class="col-md-12 text-center">
<button type="submit" class="btn btn-primary col-md-6">Ajouter</button>
</div>
</div>
</form>
The Script:
<script type="text/javascript">
$(document).ready(function(){
$("#ChangeSlideForm").on("submit", function(e){
e.preventDefault();
$.ajax({
url : $(this).attr('action'),
type : $(this).attr('method'),
data : $(this).serializeArray(),
success : function(data)
{
console.log(data)
},
error: function (xhr)
{
console.log(xhr)
}
});
});
})
</script>
Try this
public function ChangeSlide(){
print_r($this->uri->segment(3));
}
You missing parameter data in $.ajax(). So your ajax didn't send any data to your controller
When you pass value with ajax then controller method get that value as $this->input->post('id'); not as parameter.
So you have to add following to method
public function ChangeSlide($id = "")
{
}

How to pass model from view to controller when click button in MVC?

Index - View
#model SendAFaxWeb.Models.Send
//view start here
<body>
<div>
<h2>Test Upload File</h2>
<form action="#Url.Action("Index", "Home")" id="form" method="post" enctype="multipart/form-data">
#Html.AntiForgeryToken()
<div class="form-group">
<label>Fax Number:</label>
#Html.TextBoxFor(m => m.Recipients[0].Number)
</div>
<div class="form-group">
<label>Select File:</label>
<input type="file" name="files" id="file" multiple="multiple" onchange="this.form.submit();" />
</div>
<div>
#if (Model != null)
{
foreach (var item in Model.Documents)
{
<li>FileName: #item.Name</li>
}
}
</div>
</form>
<input type="submit" name="send" value="Send" id="btnSend" />
</div>
</body>
Javascript- the javascript doesnt work
<script type="text/javascript">
$(document).ready(function () {
$("#btnSend").click(function () {
alert("button click");
e.preventDefault();
var model = #Html.Raw(Json.Encode(Model))
$.ajax({
type: 'post',
url: '#Url.Action("Send", "Home")',
data: JSON.stringify({ contact: model }),
contentType: 'application/json; charset=utf-8',
dataType: "json",
success: function (data) {
alert(data);
}
});
});
});
</script>
Controller
public ActionResult Send(Send contact)
{
//some code here
}
I tried to pass model by using javascript to the controller, but its
not working. The alert in javascript also not popup. Can any one tell
me what wrong with the code.
You can do it using the below code
#model PK.LifeStyles.Web.Models.Reimbursement //model declaration on top
<button type="button" onclick="location.href='#Url.Action("ActionName", "ControllerName",Model)'">
Your code behind should look something like this
public ActionResult Save(Reimbursement data)
{
// your code
}
//just some random class
public class Reimbursement{
public string Destination { get; set; }
}
You have implemented cross origin security like : #Html.AntiForgeryToken().
So you have to pass that value as parameter in your AJAX call as below.
AJAX:
data:{__RequestVerificationToken:$('[name=__RequestVerificationToken]').val();}
Also you have to add attribute in controller.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Send(Send contact)
#using (Html.BeginForm("actionmethod", "controller", FormMethod.Post, new { }))
you can use this in view to send data from view to the controller

Call a method in a .cs from javascript

I'm stacking with the following problem: I want to create a Template witch contains forms (3 textboxes and a button).Inside this template, through a javascript, have to call a function (CRUD method) that is inside a .cs.
So...that's one of my CRUD function in EmployeeBL.cs :
[WebMethod]
public static bool CreateEmployee(int Id, string Nome, string Cognome)
{ ...}
while here it's my Employee.tpl witch should call CreateEmployee():
<div class="container" style="max-width: 400px">
<form class="form-horizontal" method="post" id="Form"
data-bv-feedbackicons-valid="glyphicon glyphicon-ok"
data-bv-feedbackicons-invalid="glyphicon glyphicon-remove"
data-bv-feedbackicons-validating="glyphicon glyphicon-refresh"
data-bv-submitbuttons='button[type="submit"]'>
<div class="form-group">
{Message}
</div>
<div class="form-group">
<input type="text" class="form-control" id="Id" placeholder="User name" value="{Model.Id}"
data-bv-notempty-message ="{UserNameNotEmptyMessage}" />
</div>
<div class="form-group">
<input type="text" class="form-control" id="FirstName" placeholder="First Name" value="{Model.FirstName}"
data-bv-notempty-message="{FirstNameNotEmptyMessage}" />
</div>
<div class="form-group">
<input type="text" id="LastName" placeholder="Last Name" value="{Model.LastName}" />
</div>
<div class="form-group">
<button type="submit" class="btn btn-default" value="Submit" id="myButton" >Create Employee</button>
</div>
Now always inside this tpl put a script like here:
<script type="text/javascript">
$(document).ready(function ()
{
$("#Form").bootstrapValidator();
$("#myButton").click(function(){
var Id=foo($('#Id').val());
var FirstName= foo($('#FirstName').val());
var LastName=foo($('#LastName').val());
});
});
Summarizing: i need to create an Employee (with Id,LastName,FirstName) that goes to write on my DB via clicking on Button
So my question is how to set visible the namespace of EmployeeBL.cs and how to call it's method CreateEmployee() inside script (clicking on Button)? Thx in advance!!
#Yuri: First of all Ty so much for help.Same time i found out that is better avoid this way. It was my fault cause i skipped telling you i'm working with ACSPNET with Owin and MVC pattern. So i created MVC files and a Business Logic one..In Controller under the function Invoke() i have to find a method to call EmployeeBL.CreateEmployee() and same time return a template like here:
public class EmployeeController : Controller<EmployeeModel>
{
public override ControllerResponse Invoke()
{
var claims = new List<Claim>{
new Claim(ClaimTypes.Name,Model.Id.ToString()),
new Claim(ClaimTypes.Name,Model.Name),
new Claim(ClaimTypes.Name,Model.Surname)
};
return newTpl(GetView<EmployeeView().Get(Model,Html.MessageBox.Show(StringTable.EmployeeModel)) , StringTable.PageTitleCreateEmployee);
}
}
where Get() function is defined in this way:
public class EmployeeView : View
{
public ITemplate Get(EmployeeModel viewModel = null, string message = null)
{
return
TemplateFactory.Load("Employee.tpl")
.Model(viewModel)
.Set().Set("Message", message);
}
}
Thus in Employee.tpl is defined only forms and button.
this should work
function createUser()
{
$.ajax({
type: "POST",
url: "YourPageName.aspx/CreateEmployee",
data: {Id: foo($('#Id').val()), Nome: foo($('#FirstName').val()),Cognome:foo($('#LastName').val()) },
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
alert('Ok'); }
error: function (request, status, thrownError) {
alert(thrownError);
}
});
}

Categories