I am trying to call an mvc 3 action method with jquery ajax. please let me note that I am generating a partial view in ajax, and in the generated partial view, I am calling ajax again (it is something like nested ajax calls). here is my code:
the partial view:
#model MYWeb.UI.Models.ClientDetailsViewModel
The javascript in the view:
<script type="text/javascript">
$(document).ready(function () {
$("#savedetails#(i)").click(function () {
var clientNumber = $('#ClientNumber#(i)').val();
var clientName = $('#ClientName#(i)').val();
var client =
{
ClientNumber: clientNumber,
ClientName: clientName
};
alert(JSON.stringify(client));
$.ajax({
url: '/Home/ClientUpdate',
type: 'POST',
dataType: 'json',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(client),
beforeSend: function () {
$("#loader#(i)_details").fadeIn('fast');
},
complete: function () {
$("#loader#(i)_details").fadeOut('fast');
},
success: function () {
$("#loader#(i)_details").fadeOut('fast');
if ($("#ModelFirstError").val())
showModelMessageError;
else
showUpdateMessageSuccess();
},
error: function () {
$("#loader#(i)_details").fadeOut('fast');
showUpdateMessageError();
},
async: true,
processData: false
});
});
});
the Model object:
public class ClientDetailsViewModel
{
[Display(ResourceType = typeof(adm), Name = "ClientNumber")]
public int ClientNumber { get; set; }
[Required(AllowEmptyStrings = false, ErrorMessageResourceName = "RequiredClientName", ErrorMessageResourceType = typeof(adm))]
[Display(ResourceType = typeof(adm), Name = "ClientName")]
public string ClientName { get; set; }
more fields...
}
the action method:
[Authorize]
[HttpPost]
public ActionResult ClientUpdate(ClientDetailsViewModel client)
{}
this attempt to update always returns the ajax error. what am I doing wrong?
Edit:
I noticed that when I remove the parameter to the action method, it does get called.
But how can I pass the model this way?
[Authorize]
[HttpPost]
public ActionResult ClientUpdate()
{}
Related
I have a view that adds an Unordered list and list items to it at runtime, then I loop through to get the entered values, push the info to an object, and do the Ajax call to my method.
I always get an empty parameter on the controller, the console.log(assetWeighJsonDetail) shows what was entered, so I'm making sure I'm not passing and empty object (see the image below):
// Client side script:
var assetSerialNumber = "";
var weight = 0;
var assetWeighJsonDetail = [];
$(".ul-asset-weigh").each(function () {
var classNameSelected = this.id;
$("." + classNameSelected).each(function () {
assetSerialNumber = $(this).attr('id');
weight = $(this).val();
assetWeighJsonDetail.push({
OriginID: classNameSelected,
AssetSerialNumber: assetSerialNumber,
Weight: weight
});
});
});
console.log(assetWeighJsonDetail);
$.ajax({
url: "/AssetWeigh/SaveAssetWeigh",
data: JSON.stringify({assetWeighJsonDetail}),
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
traditional: true,
success: function (response) {
if (response) {
alert("success");
}
else {
alert("fail");
}
},
error: function (exception) {
}
});
// Console:
// Controller Method:
[HttpPost]
public ActionResult SaveAssetWeigh(List<AssetWeighJsonDetail> assetWeighJsonDetail)
{
bool success = false;
success = assetWeighJsonDetail != null && assetWeighJsonDetail.Count > 0;
return Json(success);
}
// Method's class List parameter:
public class AssetWeighJsonDetail
{
public int OriginID { get; set; }
public string AssetSerialNumber { get; set; }
public decimal Weight { get; set; }
}
You should try with $.post I have faced the same issue if using $.ajax and was not working and just switching to $.post made it work.
$.post( "/AssetWeigh/SaveAssetWeigh", parameters, function() {
alert( "success" );
})
.done(function() {
alert( "second success" );
})
.fail(function() {
alert( "error" );
})
.always(function() {
alert( "finished" );
});
I'm on my phone and can't type all of it, I'll try to update later from my computer
This is my script:
$.fn.serializeObject = function () {
var o = {};
var a = this.serializeArray();
$.each(a, function () {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
function btnadHocSave() {
debugger
var lv_header = $("#Header").serializeObject(); // this is header <fieldset> tag
var lv_detail = $("#SubmitMachine").serializeObject(); // this is detail <fieldset> tag
$.ajax({
type: "POST",
url: '#Url.Action("UpdateMachine")',
contentType: "application/json",
dataType: "JSON",
data: {
myheader: lv_header,
mydetail: lv_detail
},
cache: false,
success: function (data) {
alert("Success!..");
},
error: function (xhr, ajaxOptions, thrownError) {
alert(thrownError);
}
})
}
This is my action code. PMAllotmentEntry and PMAllotmentDetailEntry are models:
public ActionResult UpdateMachine(PMAllotmentEntry myheader, PMAllotmentDetailEntry mydetail)
{
return View();
}
Now my problem I'm not able get the values from view to controller.
I tried JSON.stringify also but there is no use.
It is working If I pass single JSON value.
I tried out all the possibilities. Did as you said also but no use. Finally I did the following. I got two JSON values but still facing a issues because JSON second values first field value coming with first JSON values.
function btnadHocSave() {
debugger
var lv_header = $("#Header").serialize(); // this is header <fieldset>
var lv_detail = $("#SubmitMachine").serialize();
$.ajax(
{
type: "GET",
url: '/PMAllotments/UpdateMachine',
contentType: "application/json",
dataType: "JSON",
data: lv_header + ',' + lv_detail,
success: function (data) {
alert("Success!..");
debugger
$("#adHocAdd40").modal("hide");
},
error: function (xhr, ajaxOptions, thrownError) {
alert(thrownError);
}
})
}
Now I'm removed JQuery from cshtml file and simply used post method
[HttpPost]
public ActionResult UpdateMachine(PMAllotmentEntry m)
{
//complete the task
return View();
}
replaced foreach loop in .cshtml file with for loop
FOR loop is highly important foreach loop never return your child model data.
#for (int a = 0; a < Model.PMAllotmentDetail.Count; a++)
{
#* table rows here *#
}
My Model as following
[NotMapped]
public class PMAllotmentEntry
{
[Key]
public Int64 PMAllotmentId { get; set; }
[Required (ErrorMessage ="Add atleast one machine!")]
public List<PMAllotmentDetailEntry> PMAllotmentDetail { get; set; }
}
[NotMapped]
public class PMAllotmentDetailEntry
{
[Key]
public Int64 PMAllotmentDetailId { get; set; }
[ForeignKey("PMAllotmentId")]
public Int64 PMAllotmentId { get; set; }
}
I have a very specific need to serialize a model in the view and then pass it to a controller action at some point. I can get it to work by doing several hacks but its not pretty.
My test controller action
public ActionResult Index()
{
DefaultOptionValueRound defaultOptionValueRound = new DefaultOptionValueRound()
{
OptionId = 1835,
OptionValueId = 40343
};
TestModel testModel = new TestModel()
{
DefaultOptionValueRound = defaultOptionValueRound
};
return View(testModel);
}
The View
#using Common.Repository.Extensions
#model EngA.SandboxApplication.Controllers.TestModel
#Html.Hidden("DefaultOptionValueRound", Html.Raw(Json.Encode(Model.DefaultOptionValueRound)))
<input type="button" value="submit" onclick="SerializeModelTest.processOptionMag()"/>
<script language="javascript">
SerializeModelTest = {
processOptionMag: function () {
//Testing: This Works
//var defaultOptionValueRound = { OptionId: 1834, OptionValueId: 4034377 }
//var data = JSON.stringify({ defaultOptionValueRound: defaultOptionValueRound });
//This Does Not Work
var defaultOptionValueRound = $("#DefaultOptionValueRound").val();
var data = { defaultOptionValueRound: defaultOptionValueRound }; //Stringify Does not work either
$.ajax({
contentType: 'application/json; charset=utf-8',
type: "Post",
cache: false,
url: '#Url.Action("ProcessOptionMag", "SerializeModelTest")',
data: data,
dataType: "json",
traditional: true,
success: function(data) {
alert(data);
}
});
}
}
</script>
The problem is that the serialized model is returned in a stringify form already.
There must be an elegant way of doing this without me have to do JS string manipulation to make it work.
Thank you for your help
I found out that I can un-stringify my result using JSON.Parse and then repackage it with other parameters for sending to the controller.
var defaultOptionValueRound = $("#DefaultOptionValueRound").val();
var data = JSON.stringify({ defaultOptionValueRound: JSON.parse(defaultOptionValueRound) });
Now everything works.
Using Knockout I am trying to bind 3 dropdownlists with the data returned by an Ajax method calling a WebAPI.
The JSON data received is of Type "ReconDefMasters" where the calsses are defined as follows
public class MasterItem
{
public int MasterItemID { get; set; }
public string MasterItemName { get; set; }
}
public class ReconDefMasters
{
public IList<MasterItem> servFileFormat { get; set; }
public IList<MasterItem> mersRev { get; set; }
public IList<MasterItem> mersFileType { get; set; }
}
How to write the ko.mapping for this ?
I am able to achieve the result by returning IList, but then it requires 3 separate calls to the WebAPI- and trying to avoid this multiple calls by returning a composite object of 3 ILists.
I referred the below links , but not successful in modifying the logic for 3 dropdownlist together
http://jsfiddle.net/jearles/CGh9b/
Poblem with getting multidimensional array (object) observable in KnockoutJS
This is my code for single IList<> Method
var apipath = 'http://example.com';
ko.validation.init({
registerExtenders: true,
messagesOnModified: true,
insertMessages: false
});
function Master(data) {
var self = this;
self.FormatId = ko.observable(data.MasterItemID);
self.FormatName = ko.observable(data.MasterItemName);
}
var RuleDefVM = function (url) {
var self = this;
self.ServFileFormat = ko.observableArray();
self.selectedTemplate = ko.observable();
self.RuleDef = function () {
jQuery.support.cors = true;
$.ajax({
type: "GET",
url: url,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
if (response != "") {
$(response).each(function (index, element) {
self.ServFileFormat.push(new Master(element));
});
}
}
});
};
}
var urlRuleDef = apipath + '/api/RuleDef/';
var viewModelRuleDef = new RuleDefVM(urlRuleDef);
viewModelRuleDef.RuleDef();
function Master(data) {
var self = this;
self.FormatId = ko.observable(data.MasterItemID);
self.FormatName = ko.observable(data.MasterItemName);
}
selfDef.ServFileFormat = ko.observableArray();
selfDef.MERSRev = ko.observableArray();
selfDef.MERSFileType = ko.observableArray();
self.selectedTemplate1 = ko.observable();
self.selectedTemplate2 = ko.observable();
self.selectedTemplate3 = ko.observable();
jQuery.support.cors = true;
$.ajax({
url: url,
type: "GET",
dataType: "json",
contentType: "application/json; charset=utf-8",
cache: false,
success: function (response) {
if (response != "") {
$(response).each(function (index, element) {
$(element.servFileFormat).each(function (index,element) {
selfDef.ServFileFormat.push(new Master(element));
});
$(element.mersRev).each(function (index, element) {
selfDef.MERSRev.push(new Master(element));
});
$(element.mersFileType).each(function (index, element) {
selfDef.MERSFileType.push(new Master(element));
});
});
}
}
});
<select data-bind="options: ServFileFormat, value:selectedTemplate1, optionsText: 'FormatName' "class="dropdown"></select>
<select data-bind="options: MERSRev, value:selectedTemplate2, optionsText: 'FormatName' "class="dropdown"></select>
<select data-bind="options: MERSFileType, value:selectedTemplate3, optionsText: 'FormatName' "class="dropdown"></select>
I have a model which is: private int[,] mapTilesArray = new int[10, 10];
What I want to do is to use $.ajax to modify this model and then return it from controller
to my view. Then based on whatever values are inside this array I want to construct a similar array of divs in my view. So For now I don't know how to return this model to my view using json format.
my Ajax request:
var backgroundColor;
$(function () {
$(".mapTile").click(function () {
$("#info").text($(this).attr("x"));
var tile = {
X: $(this).attr("x"),
Y: $(this).attr("y")
};
$.ajax({
beforeSend: function () { ShowAjaxLoader(); },
url: "/Game/ShowTiles",
type: "POST",
contentType: "application/json;charset=utf-8",
dataType: "json",
data: JSON.stringify(tile),
success: function (data) { HideAjaxLoader(); },
error: function () { HideAjaxLoader(); }
});
});
controller:
[HttpPost]
public ActionResult ShowTiles(TileModel tile)
{
MapModel map = new MapModel();
map.MapTilesArray[tile.X, tile.Y] = 1;
return this.Content(map.MapTilesArray.ToString());
}
So how would this be done the most efficient way? How would I recreate this array in my view?
A real quick and dirty solution could be the following, you might want to tweak it a bit here and there ;)
I'm assuming you already have like 225 divs representing cells on your page, with id's going from for example cell_1 to cell_225.
View :
$.ajax({
beforeSend: function () { ShowAjaxLoader(); },
url: "/Game/ShowTiles",
type: "POST",
contentType: "application/json;charset=utf-8",
dataType: "json",
data: JSON.stringify(tile),
success: function (data) {
$.each(data, function (index, item) {
if (item) {
var cellnumber = ((item.Y * 15) + item.X);
$("#cell_" + cellnumber).innerText = item.Value;
}
});
HideAjaxLoader();
},
error: function () {
HideAjaxLoader();
}
});
Controller/Model :
public class MapModel
{
public TileModel[,] MapTilesArray;
public MapModel()
{
MapTilesArray = new TileModel[15, 15];
}
}
public class TileModel
{
public int X;
public int Y;
public int Value { get; set; }
}
[HttpPost]
public ActionResult ShowTiles(TileModel tile)
{
MapModel map = new MapModel();
map.MapTilesArray[tile.X, tile.Y] = new TileModel { X = tile.X, Y=tile.Y, Value = 1};
return Json(map.MapTilesArray);
}