Post model to controller using ajax jquery in MVC3 - asp.net-mvc-3

Can somebody help me how can I post model back to controller using jQuery and ajax.
When I post my form, my controller is receiving an empty model. Please corrent me where I am doing a mistake.
Model:
public class AllocateToStore
{
public IList<OrderLine> FailureAllocations { get; set; }
public IList<SelectListItem> AllocationStatus
{
get
{
// code to fetch list.
}
}
}
public class OrderLine
{
public long Id { get; set; }
public DateTime Date { get; set; }
public int Status { get; set; }
}
Controller:
public ActionResult AutoAllocate()
{
// This action will load the view with data.
// Get model data and send it to view.
return View("Allocated",model);
}
[HttpPost]
public ActionResult ResolveUnallocatedOrders(AllocateToStore coll)
{
// When user changes the selection in grid and post the page I need to get the selection // here. So that I can update that record.
return null;
}
And view is
#model AllocateToStore
#{
ViewBag.Title = "Orders";
}
#{
var grid = new WebGrid(Model.FailureAllocations, rowsPerPage: 100);
}
if (Model.FailureAllocations.Any())
{
<form>
<div>
#grid.GetHtml(
columns: grid.Columns(
grid.Column(columnName: "Order date", header: "Order Date", format: item => item.Order.Date),
grid.Column("dropdown", header: "Resolution", format:
#<span>
#{ var index = Guid.NewGuid().ToString(); }
#Html.Hidden("FailureAllocations.Index", index)
#Html.Hidden("FailureAllocations[" + index + "].Id", (long)item.Id)
#Html.DropDownList("FailureAllocations[" + index + "].Status", new SelectList(Model.AllocationStatus, "Value", "Text", item.Status))
</span>
)
),
tableStyle: "expandable-table",
htmlAttributes: new { id = "gridFailureAllocations" }
)
<br />
<input type="submit" value="Resolve" id="resolve-button" />
</div>
</form>
}
#section scripts
{
<script>
$("#resolve-button").click(function () {
debugger;
alert("here");
$.ajax({
url: '/OrderProcessing/ResolveUnallocatedOrders',
data: $('#form').serialize(),
type: 'POST'
});
});
</script>
}
Thanks,
Naresh

i did not test this answer .it is just suggestion . please try this way.
$.ajax({
url: o.url,
type: 'post',
contentType: "application/x-www-form-urlencoded",
data: {"FailureAllocations ":JSON.stringify(FailureAllocations), "AllocationStatus":JSON.stringify(AllocationStatus)}',
. . . .
});

I think you have a bug here data: $('#form').serialize(),
$('#form') will select all elements with the id "form". You form doesn't have an id, so your selector won't be working. Try changing that line to data: $('form').serialize(), and the selector should work.
Alternatively, give your form an id of "form" e.g. <form id="form"> and the original selector $('#form') should work.
See here for more details on the various jQuery selectors.

Related

How can I retain a template selected using ajax in dropdown of grails even after refreshing the browser?

I have a dropdown in grails with multiple options. On each option selected in dropdown , the particular template is loaded via AJAX . So, when I refresh the page the I managed to keep the dropdown value as it was but the template is not retained.
In gsp:
<div class="pull-right " id="categorydropdown">
<g:select class="selectpicker text-center" name="sortByCategories" id="sortByCategories" from="${sortByCategories}" optionKey="value" optionValue="value" value="A" onchange="getcategories()"/>
</div>
<div id="loadedtemplate"></div>
In js:
function getcategories(){
var selectedValue = $('#sortByCategories').val();
var contentdiv = $('#loadedtemplate');
$('#loading-gif').show();
$.ajax({
type: 'post',
url: htps://localhost:8080/project/getDropdownCategories',
data: 'selectedValue='+selectedValue',
success: function(data){
$(contentdiv).html(data).fadeIn('fast');
$('#loading-gif').hide();
}
}).error(function(){
$('#loading-gif').hide();
});
}
In controller:
def getDropdownCategories() {
def list= projectService.getList(params.selectedValue)
def model = [list: list]
if (request.xhr) {
if (params.selectedValue == 'A') {
render(template: "/project/listA", model: model)
}
else if(params.selectedValue=='B'){
render(template: "/project/listB", model: model)
}
}else if(params.selectedValue=='C'){
render(template: "/project/listC", model: model)
}
else if(params.selectedValue=='D'){
render(template: "/project/listD", model: model)
}
}
}

Update ViewBag dropdownlist with ajax

I am working on cascaded dropdownlist with data passed with dataview.
Controller:
public ActionResult Index()
{
ViewBag.States = new SelectList(db.PLStates, "PLStateID", "PLStateName");
ViewBag.Cities = new SelectList(db.PLCitys, "PLCityID", "PLCityName");
return View();
}
[HttpPost]
public JsonResult GetCity(int SelectedStateId)
{
SelectList result = new SelectList(db.PLCitys.Where(x => x.PLStateID == 3), "PLCityID", "PLCityName");
return Json(result);
//return Json(ViewBag.Cities = new SelectList(db.PLCitys.Where(x => x.PLStateID == 3), "PLCityID", "PLCityName"));
}
HTML:
<script type="text/javascript">
$(document).ready(function () {
$("#States").change(function () {
var SelCity1 = $("#States").val();
$("#Cities").empty();
$.ajax({
type: 'POST',
url: '#Url.Action("GetCity")',
dataType: 'JSON',
data: { SelectedStateId: SelCity1 },
success: function (Cities) {
ViewBag.Cities = Cities;
$("#Cities").append('Cities');
alert("success" + Cities);
},
error: function (ex) {
alert('Failed to retrieve states.' + ex);
}
});
return false;
})
});
</script>
<div>
#Html.DropDownList("States", "Select one")
#Html.DropDownList("Cities", "Select one")
</div>
In alert i can see the json gives back objects but the Cities dropdownlist becomes emptied with no value inside. Why ddl.cities is not filled with retured values??
Additional question is how to add style to dropdownlist??
You will have to manually add options to the cities drop down via js with the Json data returned from the controller.
As far as styling. You can style in inline by adding a "style"= to the html attributes or style with external css class using the #class html attribute.

Submitting form with file using ajax and bootstrap modal

I am trying to submit some data and file to my controller's action:
[HttpPost]
public ActionResult Settle(SettlePrepaymentViewModel settlePrepaymentViewModel)
{
//Do something and return JSON
}
My view model contains the following properties:
public HttpPostedFileBase File { get; set; }
public Guid? PrepaymentId { get; set; }
In my form I have some textboxes and a file input. When I press button, I want my form (with file) to be submitted to my action:
$('#btnConfirmSettlement').click(function (e) {
$.ajax({
url: '#Url.Action("Settle", "Prepayments")',
type: "POST",
data: $("#uploadFile").serialize(),
success: function (data) {
if (data.isSuccess) {
toastr.success("Success");
} else {
toastr.error(data.errorMessage);
}
},
error: function (data) {
toastr.error(data.errorMessage);
}
});
return false;
});
However when using the above code it does not work (there is no file passed to my action. However when using the following code (where my form is simply submitted) it works fine:
#using (Html.BeginForm("Settle", "Prepayments", FormMethod.Post, new {enctype = "multipart/form-data", #id="uploadFileSubmi"}))
{
#Html.TextBoxFor(model => model.SettlePrepaymentViewModel.File, new {type = "file"})
<input type="submit" value="Settle"/>
}
I was trying to use form submit when I click "Save" on my twitter bootstrap modal but then it just returns me (redirects me to) a JSON result from my action - I don't want to be redirected. Can someone please help me with this? What am I doing wrong?

ASP MVC 3: Client Validation not working properly when submitting a form using AJAX

I have the following scenario, I have a for that I'm submitting using ajax using the following code:
$("#cmdAjaxSave").click(function (evt) {
evt.preventDefault();
var $form = $('#frmItem');
if ($form.valid()) {
ajaxSave();
}
});
function ajaxSave() {
if (!onBeforeSubmit()) return; //item is not valid, so the ajax call should not be executed
//var token = $('[name=__RequestVerificationToken]').val();
popup('ajaxSplash');
$.ajax({
type: "POST",
url: '#Url.Action("Index")',
data: $("#frmItem").serialize(),
success: function (html) {
//console.log(html);
$("#formDiv").empty();
$("#formDiv").append(html);
initItemPage();
alert("Item was saved successfully");
},
error: function () { popup('ajaxSplash'); onFailure(); }
});
}
The problem I'm seeing here is that even though "frmItem" is returning "true" when I arrive clientside the ModelState is not valid. Specifically for three properties, which actually has the correct value.
Digging into the code made by the developer who originally coded this I found that for instance this property:
#Html.TextBoxFor(model => model.Item.Service.CPC_BW, htmlAttributes: new { #class = "Text", #onkeyup = "validItem();", #id = "SrvCPCBlk" })
Is actually defined like this:
private double _CPC_BW;
[Required]
[Range(0, 100000, ErrorMessage = "CPC value required")]
public string CPC_BW { get { return String.Format("{0:F}", _CPC_BW); } set { _CPC_BW = Convert.ToDouble(value); } }
I think he did it because TextBoxFor does not offers an obvious way to format a number and even though it looks fishy I don't know how could this be causing the error.
The Html of the form is rendered like this
<div id="itemPopUpForm">
#{Html.EnableClientValidation();}
<div id="formDiv">
#{ Html.RenderPartial("ItemData", Model, new ViewDataDictionary() { { "Machines", ViewBag.Machines }, { "WarehouseList", ViewBag.WarehouseList }, { WebConstants.FORM_ID_KEY, #ViewData[WebConstants.FORM_ID_KEY] } }); }
</div>
</div>
The partial view contains the form that is submited in the ajax request.
I think you should try and clear the model state then test whether its valid...
Its a common issue.
ModelState.Clear();
ModelState.IsValid();

Proper way to use AJAX Post in jquery to pass model from strongly typed MVC3 view

I'm a novice web programmer so please forgive me if some of my "jargon" is not correct.
I've got a project using ASP.NET using the MVC3 framework.
I am working on an admin view where the admin will modify a list of equipment. One of the functions is an "update" button that I want to use jquery to dynamically edit the entry on the webpage after sending a post to the MVC controller.
I presume this approach is "safe" in a single admin setting where there is minimal concern of the webpage getting out of sync with the database.
I've created a view that is strongly typed and was hoping to pass the model data to the MVC control using an AJAX post.
In the following post, I found something that is similar to what I am looking at doing:
JQuery Ajax and ASP.NET MVC3 causing null parameters
I will use the code sample from the above post.
Model:
public class AddressInfo
{
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
public string Country { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Check(AddressInfo addressInfo)
{
return Json(new { success = true });
}
}
script in View:
<script type="text/javascript">
var ai = {
Address1: "423 Judy Road",
Address2: "1001",
City: "New York",
State: "NY",
ZipCode: "10301",
Country: "USA"
};
$.ajax({
url: '/home/check',
type: 'POST',
data: JSON.stringify(ai),
contentType: 'application/json; charset=utf-8',
success: function (data.success) {
alert(data);
},
error: function () {
alert("error");
}
});
</script>
I have not had a chance to use the above yet. But I was wondering if this was the "best" method to pass the model data back to the MVC control using AJAX?
Should I be concerned about exposing the model information?
I found 3 ways to implement this:
C# class:
public class AddressInfo {
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
public string Country { get; set; }
}
Action:
[HttpPost]
public ActionResult Check(AddressInfo addressInfo)
{
return Json(new { success = true });
}
JavaScript you can do it three ways:
1) Query String:
$.ajax({
url: '/en/Home/Check',
data: $('#form').serialize(),
type: 'POST',
});
Data here is a string.
"Address1=blah&Address2=blah&City=blah&State=blah&ZipCode=blah&Country=blah"
2) Object Array:
$.ajax({
url: '/en/Home/Check',
data: $('#form').serializeArray(),
type: 'POST',
});
Data here is an array of key/value pairs :
=[{name: 'Address1', value: 'blah'}, {name: 'Address2', value: 'blah'}, {name: 'City', value: 'blah'}, {name: 'State', value: 'blah'}, {name: 'ZipCode', value: 'blah'}, {name: 'Country', value: 'blah'}]
3) JSON:
$.ajax({
url: '/en/Home/Check',
data: JSON.stringify({ addressInfo:{//missing brackets
Address1: $('#address1').val(),
Address2: $('#address2').val(),
City: $('#City').val(),
State: $('#State').val(),
ZipCode: $('#ZipCode').val()}}),
type: 'POST',
contentType: 'application/json; charset=utf-8'
});
Data here is a serialized JSON string. Note that the name has to match the parameter name in the server!!
='{"addressInfo":{"Address1":"blah","Address2":"blah","City":"blah","State":"blah", "ZipCode", "blah", "Country", "blah"}}'
You can skip the var declaration and the stringify. Otherwise, that will work just fine.
$.ajax({
url: '/home/check',
type: 'POST',
data: {
Address1: "423 Judy Road",
Address2: "1001",
City: "New York",
State: "NY",
ZipCode: "10301",
Country: "USA"
},
contentType: 'application/json; charset=utf-8',
success: function (data) {
alert(data.success);
},
error: function () {
alert("error");
}
});
This is the way it worked for me:
$.post("/Controller/Action", $("#form").serialize(), function(json) {
// handle response
}, "json");
[HttpPost]
public ActionResult TV(MyModel id)
{
return Json(new { success = true });
}
what you have is fine - however to save some typing, you can simply use for your data
data: $('#formId').serialize()
see http://www.ryancoughlin.com/2009/05/04/how-to-use-jquery-to-serialize-ajax-forms/ for details, the syntax is pretty basic.
If using MVC 5 read this solution!
I know the question specifically called for MVC 3, but I stumbled upon this page with MVC 5 and wanted to post a solution for anyone else in my situation. I tried the above solutions, but they did not work for me, the Action Filter was never reached and I couldn't figure out why. I am using version 5 in my project and ended up with the following action filter:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Filters;
namespace SydHeller.Filters
{
public class ValidateJSONAntiForgeryHeader : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
string clientToken = filterContext.RequestContext.HttpContext.Request.Headers.Get(KEY_NAME);
if (clientToken == null)
{
throw new HttpAntiForgeryException(string.Format("Header does not contain {0}", KEY_NAME));
}
string serverToken = filterContext.HttpContext.Request.Cookies.Get(KEY_NAME).Value;
if (serverToken == null)
{
throw new HttpAntiForgeryException(string.Format("Cookies does not contain {0}", KEY_NAME));
}
System.Web.Helpers.AntiForgery.Validate(serverToken, clientToken);
}
private const string KEY_NAME = "__RequestVerificationToken";
}
}
-- Make note of the using System.Web.Mvc and using System.Web.Mvc.Filters, not the http libraries (I think that is one of the things that changed with MVC v5. --
Then just apply the filter [ValidateJSONAntiForgeryHeader] to your action (or controller) and it should get called correctly.
In my layout page right above </body> I have #AntiForgery.GetHtml();
Finally, in my Razor page, I do the ajax call as follows:
var formForgeryToken = $('input[name="__RequestVerificationToken"]').val();
$.ajax({
type: "POST",
url: serviceURL,
contentType: "application/json; charset=utf-8",
dataType: "json",
data: requestData,
headers: {
"__RequestVerificationToken": formForgeryToken
},
success: crimeDataSuccessFunc,
error: crimeDataErrorFunc
});

Resources