Pass ID in Html.ActionLink via ajax to get partial view - c#

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

Related

Can't access to action method from JQuery if [AntiForgeryToken] is enabled

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
}
})

Pass parameter from View to controller MVC 4

I want to pass selected value of dropdownlist from view to controller in html.BeginForm in MVC 4.
I can pass value of query string, but I have no idea about how to pass selected value of dropdownlist.
All suggestions are most welcome.
Here is my code attached
<form>
<fieldset class="form-group" id="ddl2">
<label for="exampleSelect1">Section Type:</label>
#(Html.Kendo().DropDownList()
.Name("ddlsection")
.DataTextField("Name")
.DataValueField("Id")
.OptionLabel("--Select--")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetSectionType", "LookUp");
});
})
.Events(e => e.Change("onChange_ddlsection"))
.HtmlAttributes(new { #class = "form-control" })
)
</fieldset>
</form>
<div class="WordClass">
#using (Html.BeginForm("GetConditionListingInWord", "Inspection", new { sectionId = 'What should be here?' }, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input id="Submit1" type="submit" value="" class="WordClassA tooltipSource" title='Print List in MS-Word format' data-placement='bottom' data-toggle='tooltip' />
}
</div>
I want 'ddlsection' dropdown's selected value in 'What should be here?' section.
You can pass Kendo Dropdownlist's selected value to the Controller using Ajax call and then redirect to another Action if you want as shown below:
<script type="text/javascript">
$(function () {
//Returns Dropdownlist's selected values to the Controller
$("#btnSubmit").click(function (e) {
e.preventDefault();
var data = {
ProjectID: $('#ProjectID').val(), //parameter I
IssueID: $('#IssueID').val() //parameter II
}
$.ajax({
type: "POST",
url: "/Controller/Action",
cache: false,
data: JSON.stringify(data),
dataType: this.dataType,
contentType: "application/json; charset=utf-8",
success: function (data) {
// Variable data contains the data you get from the action method
window.location = "/Controller/OtherAction/" + data
},
error: function (data) {
$("#error_message").html(data);
}
});
});
});
</script>
For that you have to make AJAX call to your controler method
var userModel = {
RoleId: $("#drpRoleId").data("kendoDropDownList").value(),
}
$.ajax({
url: '#Url.Action("AddEditUser","User")',
type: 'POST',
data: JSON.stringify(userModel),
async: true,
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: function (data) {
}
});

Getting parameters for a Json controller method

I'm trying to get and pass my ViewModel to my Json method doing the stuff like this :
In my view :
<input type="button" id="suggestionBtn" title="Suggestion" onclick ="location.href='#Url.Action("GetNextAppointment", "Home", new { svm = Model })'" />
In my Controller :
public JsonResult GetNextAppointment(SuggestionViewModel svm)
{
return Json(svm, JsonRequestBehavior.AllowGet);
//this is just for testing
}
While debugging, I found out that my svm is null. I tried to replace it by a string parameter and hard coding the value in my view and this works. So, I don't know very much where is the problem.
Any idea guys?
EDIT : Code edited to use jQuery AJAX
My view's now like this :
#model AstellasSchedulerV2.Models.SuggestionViewModel
<div class="rightPanel">
#using (Html.BeginForm("NewAppointment", "Home", FormMethod.Post, new { #id = "form_ValidateAppointment" }))
{
#Html.Hidden("stringParam","")
<fieldset>
<div>
Patch Anti-douleur Corps #Html.CheckBoxFor(s => s.PADC, new { #class = "checkbox", #id = "chbxPADC" })
</div>
<br />
<div>
Patch Anti-douleur Pied #Html.CheckBoxFor(s => s.PADP, new { #class = "checkbox", #id = "chbxPADP" })
</div>
<br />
Click me
</fieldset>
}
</div>
<script type ="text/javascript">
$(document).ready(function () {
$("#ClickMe").click(function () {
var o = new Object();
o.PADC = $("#chbxPADC").val();
o.PADP = $("#chbxPADP").val();
jQuery.ajax({
type: "POST",
url: "#Url.Action("GetJson")",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(o),
success: function (data) { alert(data.PADC); },
failure: function (errMsg) { alert(errMsg); }
});
});
</script>
Here goes the solution, Lets say you have your viewmodel this way -
public class SuggestionViewModel
{
public bool PADC { get; set; }
public bool PADP { get; set; }
}
Then you have a View in the following way. Here I used JQuery to make a POST request to GetJson Controller Action. I constructed a JavaScript Object and then serialized it to Json. Then finally passed the Json string to Controller Action.
<fieldset>
<div>
Patch Anti-douleur Corps #Html.CheckBoxFor(s => s.PADC, new { #class = "checkbox", #id = "chbxPADC" })
</div>
<br />
<div>
Patch Anti-douleur Pied #Html.CheckBoxFor(s => s.PADP, new { #class = "checkbox", #id = "chbxPADP" })
</div>
<br />
</fieldset>
This is the JQuery part -
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>
$(document).ready(function () {
$("#ClickMe").click(function () {
var chk = $('#chbxPADC').is(':checked');
var chk1 = $('#chbxPADP').is(':checked');
var o = new Object();
o.PADP = chk1;
o.PADC = chk;
jQuery.ajax({
type: "POST",
url: "#Url.Action("GetJson")",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(o),
success: function (data) { alert(data.PADP); },
failure: function (errMsg) { alert(errMsg); }
});
});
});
</script>
Click me
And when you click the button, it will hit following controller -
public JsonResult GetJson(SuggestionViewModel svm)
{
return Json(svm, JsonRequestBehavior.AllowGet);
}
And when you inspect the parameter using breakpoint, you will have parameters passed -
And as the response, you will have following output -
You can't post complex objects as parameter.
If you want to get json result, you should call an ajax request.
You should post your model in an ajax request. (you can use jquery .ajax metod), because you cant get values from controller action metod if you use location.href

Jquery Post not reaching MVC Controller

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>

MVC Dialog - Get an Id value from an Action Link

In my application I have some table data that looks like this:
<table>
<tr>
<th>Actions</th>
<th>Text</th>
</tr>
#foreach( var item in Model.Items ) {
<tr>
<td>
#Html.ActionLink("Edit", "Edit", "Items", new { #class = "edit-item-link", id = "edit-item-" + item.Id })
#Html.ActionLink("Delete", "Delete", "Items", new { #class = "delete-item-link", id = "delete-item-" + item.Id })
</td>
<td>#item.Text</td>
</tr>
}
</table>
The view will create action links like the following:
Edit
I am then using jquery to override the action:
$('.edit-item-link').live('click', function(e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: ''
dataType: 'json'
});
});
When I pass the URL to the ajax call I want to use the following url: /Items/GetItemJson/1
How can I get the id value from the url without having to use a regex?
I don't want to change the url in the action link because I will be using it in another way.
The easiet approach would be to use data-* attributes
#Html.ActionLink("Edit", "Edit", "Items", new { #class = "edit-item-link", data_id=item.Id, id = "edit-item-" + item.Id })
Which should render the following:
Edit
And than in your jQuery you can use .data()
$('.edit-item-link').live('click', function(e) {
e.preventDefault();
var theId = $(this).data("id");
$.ajax({
type: 'POST',
url: ''
dataType: 'json'
});
});
Using your existing markup you could get it from the id:
var currentId = $(this).attr('id');
var id = currentId.substring(10);

Categories