Send list/array as parameter with jQuery getJson - asp.net-mvc

I have the following where I'm trying to send list/array to MVC controller method:
var id = [];
var inStock = [];
$table.find('tbody>tr').each(function() {
id.push($(this).find('.id').text());
inStock.push($(this).find('.stocked').attr('checked'));
});
var params = {};
params.ids = id;
params.stocked = inStock;
$.getJSON('MyApp/UpdateStockList', params, function() {
alert('finished');
});
in my contoller:
public JsonResult UpdateStockList(int[] ids, bool[] stocked) { }
both paramaters are null.
Note that if I change the params to single items
params.ids = 1;
params.stocked = true;
public JsonResult UpdateStockList(int ids, bool stocked) { }
then it works ok, so I don't think it's a routing issue.

Try setting the traditional flag:
$.ajax({
url: '/home/UpdateStockList',
data: { ids: [1, 2, 3], stocked: [true, false] },
traditional: true,
success: function(result) {
alert(result.status);
}
});
works fine with:
public ActionResult UpdateStockList(int[] ids, bool[] stocked)
{
return Json(new { status = "OK" }, JsonRequestBehavior.AllowGet);
}

Besides calling .ajax() instead of .getJSON() as Darin suggests or setting the global jQuery.ajaxSettings.traditional to true as jrduncans suggests, you can also pass the result of calling the jQuery .param() function on your params object:
var id = [];
var inStock = [];
$table.find('tbody>tr').each(function() {
id.push($(this).find('.id').text());
inStock.push($(this).find('.stocked').attr('checked'));
});
var params = {};
params.ids = id;
params.stocked = inStock;
$.getJSON('MyApp/UpdateStockList', $.param(params, true), function() {
alert('finished');
});

Unfortunately, while it seems that jquery provides a "traditional" flag to toggle this behavior on jQuery.ajax, it does not on jQuery.getJSON. One way to get around this would to be set the flag globally:
jQuery.ajaxSettings.traditional = true;
See the documentation for jQuery.param: http://api.jquery.com/jQuery.param/
Also see the release notes for this change: http://jquery14.com/day-01/jquery-14 (search for 'traditional')

In the view, generate multiple named fields (not id, as id should be unique per field), noting the use of Name not name:
#foreach (var item in Model.SomeDictionary)
{
#Html.TextBoxFor(modelItem => item.Value.SomeString, new { Name = "someString[]" })
}
Then retrieve the input field values using jQuery, so:
var myArrayValues = $('input[name="someString[]"]').map(function () { return $(this).val(); }).get();
You can use this directly in jQuery / AJAX as follows:
$.ajax({
type: "POST",
url: "/MyController/MyAction",
dataType: 'json',
data: {
someStrings: $('input[name="someString[]"]').map(function () { return $(this).val(); }).get(),
someDates: $('input[name="someDate[]"]').map(function () { return $(this).val(); }).get(),
Then in the controller action in MVC:
[HttpPost]
public JsonResult MyAction(string[] someStrings, DateTime[] someDates...

Related

How to pass JSON data (list created using Jquery) to an action in controller in MVC?

I have a function in jquery which creates a list of values being selected from a checkbox. Now I want to have this list in my controller action. I have converted this list to JSON but I am not able to pass it to the controller. I also tried creating a custom model corresponding to the json data.
Jquery Code
$("button").click(function () {
//alert("clicked");
var obj = {};
//var tempRadio = [];
for (var i = 1; i <= globalVar; i++) {
if ($("#" + i).prop("checked") == true) {
obj[i] = $('input[class=' + i + ']:checked').val();
}
}
$.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: 'POST',
url: '#Url.Action("SkillAdd","User")',
data: JSON.stringify(obj),
//data: hello,
error:function ()
{
alert("Error");
},
success: function () {
alert(JSON.stringify(obj));
}
});
});
Controller Code
public ActionResult SkillAdd(List<string> Id, List<string> Name)
{
return View();
}
Controller Code with Custom Model
public ActionResult SkillAdd(List<MyModel> object)
{
return View();
}
You have an object in javascript but you need to create an array so that it can be mapped to List at post. So change your js code to be :
var obj = []; // it's array now
and then you will add items in it like in your loop:
obj.push( $('input[class=' + i + ']:checked').val());
and in your ajax call name the parameter what you have in your controller action:
data:{ Id : obj }
and now you can have a parameter in action method List<string> which would hold the data posted by ajax call.
public ActionResult SkillAdd(List<string> Id)
{
return View();
}
Hope it helps.

how to add an observable property to a knockout.mapping loaded from mvc 4 class

I'm working with mvc4 and knockout trying to understand all the cool stuff you can to with it.
the thing is, i have this code which loads info and sends it to the view.
public ActionResult AdministraContenidoAlumno()
{
Alumno NuevoAlumno = new Alumno();
NuevoAlumno.AlumnoId = 1;
NuevoAlumno.NombreCompleto = "Luis Antonio Vega Herrera";
NuevoAlumno.PlanEstudioActual = new PlanEstudio
{
PlanEstudioId = 1,
NombrePlan = "Ingenieria en sistemas",
ListaMateriasPlan = new List<Materias> {
new Materias{MateriaId=1,NombreMateria="ingenieria 1"},new Materias{MateriaId=2,NombreMateria="Ingenieria 2"}
}
};
return View(NuevoAlumno);
Basically, create a new object alumno, who contains a PlanEstudio, who contains a list of Materias, then send it to the view.
In the view i have this.
#model MvcRCPG.Models.Alumno
#{
ViewBag.Title = "AdministraContenidoAlumno";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<script>
var data;
$(function () {
var jsonModel = '#Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model))';
var mvcModel = ko.mapping.fromJSON(jsonModel);
data = mvcModel;
ko.applyBindings(mvcModel);
});
function Guardar() {
$.ajax({
url: "/DemoKnockuot/GuardarAlumno",
type: "POST",
data: JSON.stringify({ 'NuevoAlumno': ko.toJS(data) }),
dataType: "json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data == "Success") {
alert('entro')
} else {
alert('trono')
}
},
error: function () {
alert("An error has occured!!!");
}
});
}
</script>
With the mentioned above functions i can read and send data to the server and do stuff on the controller, however i need to add remove or manipulate the information in the view.
So the question is: how do i add a function to 'mvcModel' in order to push a new "materia" in the ListaMateriasPlan object?
Thank you, and if you have more tips in order to understand it better i appreciate your help.
The mvcModel created by the mapping plugin will have observable properties.
For example, to add a new "materia" do something like:
function Materias() {
this.MateriaId = ko.observable();
this.NombreMateria = ko.observable();
}
var newItem = new Materias();
newItem.MateriaId(3);
newItem.NombreMateria("Ingenieria 3");
mvcModel.PlanEstudioActual.ListaMateriasPlan.push(newItem);
And normally, you would wrap the "adding" logic as a method in a view model.

How to pass the selected dropdown value to a URL in MVC?

I am developing MVC application and I am using razor syntax.
I am trying to get the selected item from dropdown list value and to pass it to the controller method.
but I am getting error.
The name 'd' does not exist in the current context
The Updated Code is...
$("#btnForword").click(function(){
d = $('#HODList').val()
alert(d);
var url2 = "#Html.Raw(Url.Action("SendPaymentAdviceForApproval", "PaymentAdvice", new { paymentAdviceId = "idValue" , nHOD = "##D##" }))"
url2 = url2.replace("idValue",'#Model.Id');
url2 = url2.replace("##D##",d);
$.ajax({
url: url2, type: "POST", success: function (data) {
$("#btnForword").css("display","none");
}
});
return false;
});
Issue solved Issue solved
The problem in variable 'D' yes in "D".
I checked using inspect element property of Google chrome, when I saw it in console window....
When I click on the button , I can see the string formed in below way
ht...../PaymentAdvice/SendPaymentAdviceForApproval?paymentAdviceId=304&nHO8=D
jquery-1.7.1.min.js:4
see the last character in the above link, it should not be come as a "=D" isnt it ?
I used the below code...and it works perfectly.
$("#btnForword").click(function(){
var url2 = "#Html.Raw(Url.Action("SendPaymentAdviceForApproval", "PaymentAdvice", new { paymentAdviceId = "idValue" , nHOD = "HODId" }))";
url2 = url2.replace("idValue",'#Model.Id');
url2 = url2.replace("HODId",$('#HODList').val());
$.ajax({
url: url2, type: "POST", success: function (data) {
$("#btnForword").css("display","none");
}
});
return false;
});
Is this a bug in Jquery ?
You should use data property of $.ajax to pass parameter to controller-action.
$("#btnForword").click(function(){
var d = document.getElementById("HODList").value;
// define url
var url2 = 'Url.Action("SendPaymentAdviceForApproval", "PaymentAdvice")';
//url2 = url2.replace("idValue",'#Model.Id');
//url2 = url2.replace("d",'#d');
$.ajax({
url: url2,
type: "POST",
// add parameters in here...
data: { paymentAdviceId : #Model.Id, nHOD : d }
success: function (data) {
$("#btnForword").css("display","none");
}
});
return false;
});
And your controller should looks:
public ActionResult SendPaymentAdviceForApproval(int paymentAdviceId, int nHOD){...}
Try this
$(function(){
$("#btnForword").click(function(){
var d = $('#HODList').val();
var url2 = "#Html.Raw(Url.Action("SendPaymentAdviceForApproval", "PaymentAdvice", new { paymentAdviceId = "idValue" , nHOD = "##D##" }))";
url2 = url2.replace("idValue",'#Model.Id');
url2 = url2.replace("##D##",d);
$.ajax({
url: url2, type: "POST", success: function (data) {
$("#btnForword").css("display","none");
}
});
return false;
});
});
don't consider replacing "d" as it will affect your other part of url as well.. Try specific placeholder instead.
If this not works... Then can you please show Signature of your Action method too?
Your controller action should be like this
[HttpPost]
public JsonResult SendPaymentAdviceForApproval(int paymentAdviceId, int nHOD)
{
// Your existing logic here...
}
Cheers

Returning List as Json and viewbag from same controller action

I am working on asp.net MVC 3 applciation. I have a jquery ui dialog. On Ok button of this dialog, I am opening another jquery ui dialogue. In order to populate the newly opened popup, I am using jquery ajax call which returns a collection. I am using this collection to create table rows. Code is here:
$("#Prices").dialog({
autoOpen: false,
autoResize: true, buttons: {
"OK": function () {
var PirceCurrencies = $('#PirceCurrencies').val();
jQuery("#hdCurrencyId").val(PirceCurrencies);
jQuery(this).dialog('close');
$.ajax({
type: "POST",
dataType: "json",
url: "/Home/GetRecordingRates",
data: { Id: $("#hdCurrencyId").val() },
success: function (data) {
$("#results").find("tr:gt(0)").remove();
var messages = data.Result;
$.each(messages, function(k, v) {
var row = $('<tr>');
row.append($('<td>').html(v.DialPrefix));
row.append($('<td>').html(v.Rate));
$('#results').append(row);
});
jQuery('#RecordingRates').dialog({ closeOnEscape: false });
$(".ui-dialog-titlebar").hide();
$("#RecordingRates").dialog({ dialogClass: 'transparent' });
$('#RecordingRates').dialog('open');
}
});
}
},
open: function () {
$('.ui-dialog-buttonset').find('button:contains("OK")').focus();
$('.ui-dialog-buttonset').find('button:contains("OK")').addClass('customokbutton');
}
});
and controller action is:
public JsonResult GetRecordingRates(int Id)
{
List<DefaultRateChart> defaultRateCharts = new List<DefaultRateChart>();
Currency currency = new Currency();
using (IDefaultRateChartManager defaultRateChartManager = new ManagerFactory().GetDefaultRateChartManager())
{
defaultRateCharts = defaultRateChartManager.GetAll().Where(rc => rc.Currency.Id == Id
&& (!rc.NumberPrefix.StartsWith("#") && !rc.NumberPrefix.Equals("Subscription")
&& !rc.NumberPrefix.Equals("Default")) && rc.AccountCredit == "Credit").ToList();
}
using (ICurrencyManager currencyManager = new ManagerFactory().GetCurrencyManager())
{
currency = currencyManager.GetById(Id);
ViewBag.currecycode = currency.CurrencyCode;
ViewBag.countrycode = currency.CountryCode;
}
return this.Json( new {
Result = ( from obj
in defaultRateCharts
select new {
Id = obj.Id,
DialPrefix = obj.NumberPrefix,
Rate = obj.PurchaseRates
}
)
}, JsonRequestBehavior.AllowGet);
}
All this works fine but I need to show some other data on newly opened popup other than the collection which populates/create html table rows. Fort that do I need to make another ajax call to another controller action which will return the data ?
Please suggest
Look at what you return now in your controller:
new {
Result = ( ... )
}
You are returning an object with 1 property named Result. In your javascript code you get that object returned named data and you retrieve the Result property as your list.
What stops you from adding more properties to that list?
new {
result = ( ... ),
currencyCode = currency.CurrencyCode,
countryCode = currency.CountryCode
}
In javascript you can then use data.currencyCode and data.countryCode
From Controller Action Method you can Return Dictionary like below.
Sample Code - C#
var dic = new List<KeyValuePair<short, object>>
{
new KeyValuePair<Int16, object>(1, SomeObj),
new KeyValuePair<Int16, object>(2, SomeObj),
new KeyValuePair<short, object>(3, SomeObj),
new KeyValuePair<Int16, object>(4, SomeObj)
};
return Json(dic, JsonRequestBehavior.AllowGet);
Sample Code - JQuery- Access Dictionary objects
var obj1; //Global Variables
var obj2; //Global Variables
var obj3; //Global Variables
var obj4; //Global Variables
$.ajax({
url: url,
async: true,
type: 'GET',
data: JSON.stringify({ Parameter: Value }),
beforeSend: function (xhr, opts) {
},
contentType: 'application/json; charset=utf-8',
complete: function () { },
success: function (data) {
DataSources(data);
}
});
function DataSources(dataSet) {
obj1 = dataSet[0].Value; //Access Object 1
obj2 = dataSet[1].Value; //Access Object 2
obj3 = dataSet[2].Value; //Access Object 3
obj4 = dataSet[3].Value; //Access Object 4
}
return a Dictionary from your controller.
convert your collection to string and other object to string and return
dictionary<int, string>
in your javascript sucess function,
JSON.parse(data[0].key) will give you your collection
This will give you an idea
bool inCart = false;
Cart MyCart = default(Cart);
Dictionary<string, string> Result = new Dictionary<string, string>();
Result.Add("inCart", inCart.ToString().ToLower());
Result.Add("cartText", MyCart.CartText());
string ResultString = new JavaScriptSerializer().Serialize(Result);
return ResultString;
Here I am adding two types to a dictionary and returning my serialized dictionary

Pass checkboxes to controller asp.net mvc

I have some images that every images has a checkbox beside like this :
<input type="checkbox" name="select" value="<%=item.Id%>" />
Now I want to send the selected checkboxes to controller by clicking a hyperlink. I have :
<a href='<%: Url.Action("DeleteSelected", "Product", new { #ShopID = ViewBag.shopIDempty } ) %>'>Delete</a>
and in controller:
public ActionResult DeleteSelected(int[] select, int ShopID)
{
foreach (int checkBoxSelected in select)
{
//Do something...
}
return RedirectToAction("Index");
}
But nothing pass to int[] select and it is null always. What is wrong?
Do these==>
1) Make an array which contains the selected checkbox value
var delete= new Array();
$('.checkboxed').live('click', function () {
if ($(this)[0].checked == true) {
var itemdel= $(this).val();
delete.push(itemdel);
} else {
var remve = $(this).val();
for (var i = 0; i < delete.length; i++) {
if (delete[i] == remve) {
delete.splice(i, 1);
break;
}
}
}
});
2)Make an ajax call on clicking the hyper link
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
url: '/Product/DeleteSelected'
+ '?ShopID =' + ShopIdValue,
dataType: 'json',
data: $.toJSON(delete),
success: function (result) {
window.location.href=result;
},
async: false,
cache: false
});
3) Make your Action Like this
public ActionResult DeleteSelected(int[] select)
{
var shopid= Request["ShopID "];
}
Try this:
[HttpPost]
public ActionResult DeleteSelected(FormCollection collection)
{
try
{
string[] test = collection.GetValues("select");
}
catch (Exception ex)
{
return null;
}
}
I do want to note that the approach you are taking requires a form to wrap the all of the checkboxes or you need to specifically build an object to send to the controller as Syed showed. If you go the form approach, you will need to either use the a link to trigger the form submit or convert the a link to a submit button and have a hidden field for the ShopID.

Resources