Apologies if this i trivial, i have read many other comments and still cannot see what is wrong. I have done a few tutorials and they seem to work ok, so I am really missing something simple.
I have a basic 'remove' link that i want to do a JQuery Post back to the controller to remove an item from the database and then update the view.
My View / Javascript:
<script type="text/javascript">
$(function () {
$(".RemoveLink").click(function () {
var id = $(this).attr("data-id");
if (id != '') {
$.post("#Url.Content("~/Agent/Remove")", { "id": id }, function (data) { alert('Here i am'); });
}
});
});
#foreach (var item in Model.Object) {
<tr id="row-#item.ID">
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
<a href="#" class="RemoveLink" data-id="#item.ID" >Remove</a>
</td>
</tr>
}
My Controller:
[HttpPost]
public ActionResult Remove(int id)
{
return Json(new { Data = "true" });
}
Any assistance will be great.
Use #Url.Action("Remove", "Agent") instead.
#Url.Content("...") is used to locate any static content of the site.
Cheers
Below code works well.
#foreach (var item in Model.Object) {
<tr id="row-#item.ID">
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
<input type="button" class="RemoveLink" id="#item.ID" Value="Remove" />
</td>
</tr>
}
<script type="text/javascript" language="javascript">
$(document).ready(function () {
$('.RemoveLink').live("click", function () {
Remove($(this));
});
});
function Remove(_this) {
var Id= $(_this).attr('id');
$.ajax({
type: 'POST',
url: '#Url.Action("Remove", "Agent")',
data: "{id: '" + Id + "'}",
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (data) {
//do something here......
},
error: function () {
}
});
}
</script>
Related
I am using DataTable library in MVC, but it doesn't work
this is the view Part
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>Id</th>
<th>Phone</th>
<th>FirstName</th>
<th>LastName</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<th>Id</th>
<th>Phone</th>
<th>FirstName</th>
<th>LastName</th>
</tr>
</tfoot>
</table>
<script type="text/javascript">
//$(document).ready(function () {
// $('#example').DataTable();
//})
$(document).ready(function () {
GetEmployeeRecord();
})
var GetEmployeeRecord = function () {
$.ajax({
type: "Get",
url: "/BasicInfo/GetCustomers",
success: function (response) {
alert("success");
BindDataTable(response);
},
error: function () {
alert("error");
}
})
}
var BindDataTable = function (response) {
$("#example").DataTable({
"aaData": response,
"aoColumns": [
{ "mData": "Id" },
{ "mData": "Phone" },
{ "mData": "FirstName" },
{ "mData": "lastName" }
]
});
}
and this is Controller Part
public JsonResult GetCustomers()
{
SalonEntities db = new SalonEntities();
List<Customer> CustomerList = db.Customers.OrderByDescending(a => a.ID).ToList();
return Json(CustomerList , JsonRequestBehavior.AllowGet);
}
although the CustomerList in controller is loaded but it returns to the view it enters the error section of jquery
what could be the problram
The ajax call to your controller failed. To debug this, you can do two things:
Alert the error
Remove the (dobule quote) " to alert the actual error.
error: function () {
alert(error);
}
You will most probably be able to see it in developer tools in your console.
Check the network tab
In your network tab, you'll see the error (4XX, 5XX) or something like that with some extra information (if you are lucky).
If no more information is there and you have an error 500, you need to check the exception in your backend code.
I have a JQuery function that works ok but if I enable [AntiForgerToken] on the Action Method the JQuery function can't access the Action Method, on the view I have other snippet where I enabled AntiForgeryToken:
#using (Html.BeginForm("InsertStudent","Students",FormMethod.Post, new { #id="myform"}))
{
#Html.AntiForgeryToken()
It doesn't matter if the #Html.AntiForgeryToken() inside the view is enabled or not, the JQuery function works good, the one with the problem is at the Action Method...
Why is happening that? What I'm missing?? I've read is very important for security to have [AntiForgeryToken] enabled on the Post Action Methods so I think that the application should work with it enabled in both places the Action Method and the View.
JQuery function:
function InsertShowStudents() {
var counter = 0;
$.ajax({
type:"post",
url: "/Students/InsertStudent/",
data: { Name: $("#Name").val(), LastName: $("#LastName").val(), Age: $("#Age").val() }
}).done(function (result) {
if (counter==0) {
GetStudents();
CounterStudents();
counter = 1;
}
else {
$("#tableJQuery").append("<tr>"+"<td>"+result.Name+"</td>"+"<td>"+result.LastName+"</td>"+"<td>"+result.Age+"</td>"+"</tr>")
}
//clear the form
$("#myform")[0].reset();
}).error(function () {
$("#divGetStudents").html("An error occurred")
})
}
Action method:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult InsertStudent(Student student)
{
if (ModelState.IsValid)
{
db.Students.Add(student);
db.SaveChanges();
//ModelState.Clear();
return RedirectToAction("InsertStudent");
}
return View(student);
}
columns of the table:
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Age)
</td>
#* <td style="display:none" class="tdStudentID">#Html.DisplayFor(modelItem => item.StudentID)</td> *#
<td>
<img src="~/images/deleteIcon.png" width="20" height="20" class="imgJQuery" data-id="#item.StudentID" />
</td>
<td>
#Html.ActionLink("Details","Details", new { id=item.StudentID})
</td>
</tr>
}
You not passing the value of the token in your ajax call so an exception is thrown. You can get the value of the token using
var token = $('[name=__RequestVerificationToken]').val();
and modify your ajax call to include it using
data: { __RequestVerificationToken: token, Name: $("#Name").val(), LastName: $("#LastName").val(), Age: $("#Age").val() }
however, it is easier to just serialize your form which will include the token
$.ajax({
type:"post",
url: '#Url.Action("InsertStudent", "Students")', // don't hardcode your url's
data: $('#myform').serialize(),
}).done(function (result) {
Side note: Ajax calls never redirect (the whole point of ajax is to stay on the same page) so having return RedirectToAction("InsertStudent"); in your InsertStudent() will not work. In addition, your returning html, so the $("#tableJQuery").append() code in the .done() callback will fail.
It appears you have a form to add a new Student so your method simply need to return a JsonResult indicating success or otherwise, and if successful, then you can add a new row to your table based on the values in the form, for example
}).done(function (result) {
if (result) {
var row = $('<tr></tr>');
row.append($('<td></td>').text($("#Name").val()));
... // add other cells
$("#tableJQuery").append(row);
//clear the form
$("#myform")[0].reset();
} else {
// Oops something went wrong
}
})
I will show you all the moving parts involved.
View:
#{
ViewBag.Title = "Partners";
}
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<h1>Partners</h1>
<p>Click to see survey answers or delete partner</p>
<table class="table">
<thead>
<tr>
<th>Partner Name</th><th>Actions</th>
</tr>
</thead>
<tbody>
#foreach ( var NameIdPair in ViewBag.PartnersAndIds )
{
<tr>
<td>
#NameIdPair.Name
</td>
<td>
<button class="btn btn-info view-partner-surveys" data-partnerid="#NameIdPair.Id">View Survey Answers</button>
<button class="btn btn-warning delete-partner" data-partnerid="#NameIdPair.Id">Delete Partner</button>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
#section bottommost {
<script type="text/javascript">
$('.delete-partner').click(function () {
var row = $(this).closest('tr');
$.ajax({
method: 'POST',
url: 'DeletePartner',
data: { pid: $(this).attr('data-partnerid') },
dataType: 'json',
processData: false,
beforeSend: function () {
row.addClass('processing');
},
success: function (retinfo) {
if (retinfo.DeletedSuccessfully) { row.remove(); }
else { alert("Error .."); row.removeClass('processing'); }
},
error: function () { alert("Error"); row.removeClass('processing'); }
});
});
</script>
}
The problem is occuring with the AJAX call invoked with $('.delete-partner').click. The controller handling the request is the simple
[HttpPost]
public ActionResult DeletePartner ( int pid )
{
return Json(new { DeletedSuccessfully = this._Db.DeletePartner(pid) });
}
which used the method DeletePartner in a model defined by
public bool DeletePartner ( int id )
{
SqlCommand cmd = new SqlCommand("DeletePartner", this._Conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#id", id);
this._Conn.Open();
bool succeeded = cmd.ExecuteNonQuery() == 1 ? true : false;
this._Conn.Close();
return succeeded;
}
The sproc its calling is the simple
CREATE PROCEDURE DeletePartner
#id INT
AS
DELETE FROM Partners WHERE id=#id
Any idea where I'm going wrong here?
You should use the url of your ajax call like following.
url: '#Url.Action("DeletePartner")'
You have to give ajax url in the format like
url : '../controllerName/ActionName'
[HttpPost]
public ActionResult DeletePartner ( int pid )
{
return Json(new { DeletedSuccessfully = this._Db.DeletePartner(pid) });
}
The DeletedSuccessfully variable is not recognised by the controller. So it may cause 500 error
I display a list of element from a list, and I have to display a checkbox in front of each element, and then delete all checked element, I wrote a jquery code for do this but it removes just the first element checked, how I should do to remove all checked items
<button type="submit" class="btn fsc-btn-3" id="AllDelete">
<i class=" fa fa-check"></i>
<span>#Labels.Global_DeleteSelection</span>
</button>
#foreach (var item in Model.FilesList)
{
<tr>
<td><input type="checkbox" name="checkFile" id="checkFile" value="#item.FileId" /></td>
<td>#item.ArrivalTime</td>
<td>#Model.TraitementDate(item.FileId)</td>
<td>#item.Name</td>
<td>#item.FileType</td>
<td>
<label class="proj-label-1 proj-label-size-1 proj-status-5" title="#item.State">
<i class="fa fa-check-circle"></i>
<span>#item.State</span>
</label>
</td>
<td >#item.NumAlertRecords</td>
<td>#item.NumRejectedRecords</td>
<td >#item.NumAcceptedRecords</td>
}
jQuery code:
(function(jQuery) {
jQuery(function() {
jQuery('#AllDelete').click("click", function() {
jQuery('input[type="checkbox"]').each(function() {
if (jQuery(this).is(':checked')) {
alert(jQuery("#checkFile").val());
jQuery.ajax({
url: '#Url.Action("DeleteMultiCredit", "DeleteCredit")',
type: "POST",
dataType: "json",
data: { FileId: jQuery("#checkFile").val() },
success: function (data) { }
})
}
});
});
});
})(jQuery);
Controller :
[HttpPost]
public ActionResult DeleteMultiCredit(int FileId)
{
DeleteCreditModel model = new DeleteCreditModel();
model.Delete(FileId);
return RedirectToAction("Index");
}
Try this : first of all you cannot use same id for all checkbox, so either generate unique ids for each one or remove id attribute
#foreach (var item in Model.FilesList)
{
<tr>
<td><input type="checkbox" name="checkFile" value="#item.FileId" /></td>
<td>#item.ArrivalTime</td>
<td>#Model.TraitementDate(item.FileId)</td>
<td>#item.Name</td>
<td>#item.FileType</td>
<td>
<label class="proj-label-1 proj-label-size-1 proj-status-5" title="#item.State">
<i class="fa fa-check-circle"></i>
<span>#item.State</span>
</label></td>
<td >#item.NumAlertRecords</td>
<td>#item.NumRejectedRecords</td>
<td >#item.NumAcceptedRecords</td>
}
now use $(this).val() to get value of each checkbox instead of using id of checkbox to read value
jQuery(function () {
jQuery('#AllDelete').click("click", function () {
//you can use :checked directly in selector, so if condition not required
jQuery('input[type="checkbox"]:checked').each(function() {
alert(jQuery(this).val());
jQuery.ajax({
url: '#Url.Action("DeleteMultiCredit", "DeleteCredit")',
type: "POST",
dataType: "json",
data: { FileId: jQuery(this).val() },//read your value here
success: function (data) {
}
});
});
});
})(jQuery);
Use jQuery(this) instead of jQuery("#checkFile")
Just like this :
(function(jQuery) {
jQuery(function() {
jQuery('#AllDelete').click("click", function() {
jQuery('input[type="checkbox"]').each(function() {
if (jQuery(this).is(':checked')) {
alert(jQuery(this).val());
jQuery.ajax({
url: '#Url.Action("DeleteMultiCredit", "DeleteCredit")',
type: "POST",
dataType: "json",
data: { FileId: jQuery(this).val() },
success: function (data) { }
})
}
});
});
});
})(jQuery);
try below code
jQuery(function () {
jQuery('#AllDelete').click(function () {
jQuery('input[type="checkbox"]').each(function() {
if(this.checked){
alert(jQuery("#checkFile").val());
jQuery.ajax({
url: '#Url.Action("DeleteMultiCredit", "DeleteCredit")',
type: "POST",
dataType: "json",
data: { FileId: jQuery(this).val() },
success: function (data) { }
})
}
});
});
});
})(jQuery);
I have an MVC View page, strongly-typed to an enumerated product list. Each list item has an Html.ActionLink with a unique id. In my jquery file, I have an $.ajax function which should process the link with the corresponding id . The intent is to load a partial view on the same page, with that item's information, to allow editing for whatever item has been clicked. I don't want the actionr to result in a separate page, or generate a post to the server.
// here is the MVC stuff
#model IEnumerable<SimpleAjax.Models.Product>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Price)
</td>
<td>
#Html.ActionLink("Edit", "ShowEdit", "Home", new { id=item.Id } ,new { id = "btnShowEdit" + item.Id, #class= ".button_action"})
|
</td>
</tr>
}
<div id="showEditProd">
</div>
//inside controller
public ActionResult ShowEdit(int id)
{
Product prod = db.Product.Find(id);
ProductViewModel viewModel = new ProductViewModel
{
EditProduct = prod
};
return PartialView(viewModel);
}
//inside a separate partial view page
#model SimpleAjax.Models.ProductViewModel
#using (Html.BeginForm("Index_AddItem", "Home", FormMethod.Post, new { id = "fid" }))
{
<div>
#Html.LabelFor(model => model.EditProduct.Name)
#Html.EditorFor(model => model.EditProduct.Name)
</div>
<div>
#Html.LabelFor(model => model.EditProduct.Price)
#Html.EditorFor(model => model.EditProduct.Price)
</div>
<div>
<input type="submit" value="Submit" />
</div>
}
now below works as expected, when I have hardcoded IDs:
$('#btnShowEdit1,#btnShowEdit2,#btnShowEdit3').click(function () {
$.ajax({
url: this.href,
contentType: 'application/html; charset=utf-8',
type: 'GET',
success: function (result) {
$('#showEditProd').html(result);
}
});
return false;
});
The above jquery works as desired. The partial view gets loaded on the same page as enumerated list. But obviously I don't want to hardcode variables. I may have x number of #btnShowEdit. I want to utilize a class, correct? So I have ".button_action" class that will enumerate the Id. But when I do that, as below, the link navigates to a separate page.
these go to a separate page, not what I want
$('.button_action').click(function (index) {
$.ajax({
url: this.href,
contentType: 'application/html; charset=utf-8',
type: 'GET',
success: function (result) {
$('#showEditProd').html(result);
}
});
return false;
});
});
//also tried this...
$('.button_action').each(function (index) {
$('#btnShowEdit' + index).click(function () {
$.ajax({
url: this.href,
contentType: 'application/html; charset=utf-8',
type: 'GET',
success: function (result) {
$('#showEditProd').html(result);
}
});
return false;
});
});
I know there's gotta be a simple solution.Thanks for your help in advance.
Any specific reason for not using the Ajax HTML-helper?
http://msdn.microsoft.com/en-us/library/system.web.mvc.ajax.ajaxextensions.actionlink(v=vs.108).aspx
You can use it as an actionlink, but it is done async and the result can be placed in your showEditProd.
#Ajax.ActionLink("Action",
"Controller",
_YOURID_,
new AjaxOptions { HttpMethod = "GET",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "showEditProd",
OnComplete = "your_js_function();" })
In case anyone else needs the solution to the above... It was too simple to believe.The jquery ajax code does not need an id htmlattribute from the Html.ActionLink. In fact, this extra attribute is what was causing the trouble. The jquery ajax recognizes the id from the "this.href' as that is the route controller along with the id parameter. Therefore I removed the id from htmlattributes in the actionlink. Now it's working as expected.
#Html.ActionLink("Edit", "ShowEdit", "Home", new { id=item.Id } ,new { #class= ".button_action"})
in js file
$('.button_action').click(function (index) {
$.ajax({
url: this.href,
contentType: 'application/html; charset=utf-8',
type: 'GET',
success: function (result) {
$('#showEditProd').html(result);
}
});
return false;
});
});
Check this:
$('.button_action').click(function (e) {
e.preventDefault() // this prevent default behavior for hyperlink on 'click' event