how i could iterate over json array of array - asp.net-mvc

i want to iterate over a json array of arrays from th controller i want to know how i could iterate over it
i need help: nay could help me i'm new to json and mvc
//server code
var jsonData = new
{
rows =
(from bathymetrie in bathymetries
select new
{
count = bathymetries.Count,
Id = bathymetrie.Id,
date = (bathymetrie.displayedDate != null) ?
bathymetrie.displayedDate.ToString() : ""
}).ToArray()
};
//client code
success: function (data) {
bathyms = "{";
for (var i = 0; i < data[1].count; i++) {
bathyms += el[i].Id + " : " + el[i].date;
alert(el[i].Id);
alert(el[i].date);
console.log(el[i].date);
if (i != data[0].count) {
bathyms += ",";
}
}
bathyms += "}";
}

Your data is an object with single field row, which contains an array of objects. Thus, iteration should look like this:
for (var i = 0; i < data.rows.length; i++) {
var element = data.rows[i];
// use element.Id, element.count and element.date

Say if you have your model like this -
public class Data
{
public int Id { get; set; }
public int Count { get; set; }
public string Date { get; set; }
}
And you are returning JsonResult of Array object like this -
public ActionResult GetJson()
{
Data[] a = new Data[2];
a[0] = new Data() { Count = 10, Id = 1, Date = "2/19/2014" };
a[1] = new Data() { Count = 20, Id = 2, Date = "3/19/2014" };
return new JsonResult() { Data = a };
}
Then you can invoke this action in JQuery in the following way -
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>
function submitForm() {
jQuery.ajax({
type: "POST",
url: "#Url.Action("GetJson")",
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (data) {
$.each(data, function (key, value) {
alert(value.Id + ' ' + value.Count + ' ' + value.Date);
});
},
failure: function (errMsg) {
alert(errMsg);
}
});
}
</script>
<input type="button" value="Click" onclick="submitForm()" />
Please observe following code which will iterate array -
success: function (data) {
$.each(data, function (key, value) {
alert(value.Id + ' ' + value.Count + ' ' + value.Date);
});
Output would be N number of alerts based on N elements in array like below -

Related

How to convert array to send as query string?

In my view, I have checkboxes and some data displayed and button on each row to approve or reject requests put up.
I want to send my integer array to my action method but this cannot be done by just sending it to action query parameters and it would be like the picture below:
public int[] Ids
{
get { return new int[] { 1, 2, 3 }; }
set {}
}
public ActionResult Approval([ModelBinder(typeof(IntArrayModelBinder))] int[] ids)
{
...
return View(...);
}
#Html.ActionLink("Approve", "Approval", new {id = item.Ids, approvalAction = "approve"})
How do I implement the checkboxes to be checked and hover of the approve/reject actionlink will show the url with ../ids=1&ids=2&ids=3 instead of System.Int32[]?
Option 1: Send your array as a comma-separated string and then split them in your action like this :
#Html.ActionLink("Approve", "Approval", new { id = string.Join("," , Ids), approvalAction = "approve" } )
your action :
public ActionResult YourAction(string id , string approvalAction)
{
var ids = id.Split(',');
//rest of your action method business
}
Option 2:
another way to achieve your exactly url is to create your URL like this :
var baseUrl = Url.Action("YourAction", "YourController", null, Request.Url.Scheme);
var uriBuilder = new UriBuilder(baseUrl);
uriBuilder.Query = string.Join("&", Ids.Select(x => "ids=" + x));
string url = uriBuilder.ToString();
url += "&approvalAction=approve"
and your action would be like this :
public ActionResult YourAction(int[] ids , string approvalAction)
{}
<script>
function multiSelect(selectedArray, action) {
if (selectedArray[0] === undefined) {
alert("You have not selected any employee");
}
//example url
//..?ids=1&ids=2&ids=3&aprovalAction=approve
else {
var param = "";
var currUrl = "";
var idUrl = "";
idUrl = "ids=" + selectedArray[0];
for (var i = 1; i < selectedArray.length; ++i) {
idUrl += "&ids=" + selectedArray[i];
}
switch (action) {
case "Approve":
param = "approve";
break;
case "Reject":
param = "reject";
break;
}
currUrl = "approvalAction=" + param;
window.location.href = "?" + idUrl + "&" + currUrl;
}
}
</script>
<script>
$('#MultiApproveBtn').click(function () {
var selected = $('input[type=checkbox]:checked').map(function (_, el) {
return $(el).val();
}).get();
var x = document.getElementById("MultiApproveBtn").value;
//alert(selected);
multiSelect(selected, x);
})
</script>
<script>
$('#MultiRejectBtn').click(function () {
var selected = $('input[type=checkbox]:checked').map(function (_, el) {
return $(el).val();
}).get();
var x = document.getElementById("MultiRejectBtn").value;
//alert(selected);
multiSelect(selected, x);
})
</script>

Stop process if condition is null and return message

I have a controller like this:
public ActionResult CargaCSV(HttpPostedFileBase archivo)
{
List<string[]> registros = new List<string[]>();
confService = new ConfiguracionService();
if (archivo.ContentLength > 0)
{
StreamReader sR = new StreamReader(archivo.InputStream);
string linea;
string resultado = "";
var f = 0;
while ((linea = sR.ReadLine()) != null)
{
if (f == 0)
{
f++;
continue;
}
else
{
String[] registros_ = linea.Split(',');
registros.Add(registros_);
}
}
sR.Close();
ViewBag.Message = resultado;
confService.GuardarMatrizCsv(registros,usuarioCaptura);
}
return Json(registros);
}
As you can see I return result into div:
ViewBag.Message = resultado;
View:
<div class="" style="height: 150px; overflow: auto; margin-bottom:10px;">
<pre id="resultado">#ViewBag.Message</pre>
</div>
That I want to do is to cancel all proccess if (archivo.ContentLength > 0) return null and return: ViewBag.Message = "you need attach file to load it"; and stop all process
How can I achieve this?
Update:
I call CargaCSV method with ajax call:
$("#btnCargarCsv").on("click", function () {
var data = new FormData();
data.append("archivo", $("#archivo")[0].files[0]);
$.ajax({
"type": "POST",
"url": "/Configuracion/CargaCSV",
"contentType": false,
"processData": false,
"data": data,
success: function (s) {
var result = $("#resultado");
result.text("");
result.append("<table>");
result.append("<tr>");
result.append("<th> Unidad </th>");
result.append("<th> CR Mínimo </th>");
result.append("<th> CR Máximo </th>");
result.append("<th> % Mínimo </th>");
result.append("<th> % Máximo </th>");
result.append("</tr>");
for (var i = 0; i < s.length; i++) {
var val = s[i];
result.append("<tr>");
result.append("<td> " + val[0] + " </td>");
result.append("<td> " + val[1] + " </td>");
result.append("<td> " + val[2] + " </td>");
result.append("<td> " + val[3] + " </td>");
result.append("<td> " + val[4] + " </td>");
result.append("</tr>");
}
result.append("</table>");
}
});
});
So here I append data into table and show data into pre html tag "resultado"
Your returning a JsonResult, not a ViewResult, so setting a ViewBag property is pointless (ViewBag is for passing data to a View) and your
<pre id="resultado">#ViewBag.Message</pre>
element will only ever display the initial value of ViewBag.Message when the page is first rendered.
You need to return the message in your JsonResult and test it in the ajax success method.
Change the controller code to return different values based on your condition
public ActionResult CargaCSV(HttpPostedFileBase archivo)
{
if (archivo.ContentLength = 0)
{
string message = "you need attach file to load it";
return Json( new { message = message });
}
.... // your code to process the file
return Json(new { registros = registros });
}
and change the code in the success callback to test the result
success: function (data) {
if (data.message) {
$('#resultado').text(data.message);
} else if (data.registros) {
var result = $("#resultado");
....
for (var i = 0; i < data.registros.length; i++) {
var val = data.registros[i];
....
}
result.append("</table>");
}
}
As a side note, you could simplify your script by generating the <table> and its headings (which should be in a <thead> element) in the view (and style it using display: none;and just add the <tr> elements inside its <tbody> element (and then show/hide the table in the success callback), for example
<table id="resultstable" style="display:none">
<thead>
....
</thead>
<tbody id="results"></tbody>
<table>
Script
var table = $('#resultstable');
var results = $('#results');
var message = $('#resultado');
$('btnCargarCsv').on('click', function () {
....
$.ajax({
....
success: function (data) {
if (data.message) {
message.text(data.message);
table.hide();
} else if (data.registros) {
results.empty(); //remove any existing rows
table.show();
for (var i = 0; i < data.registros.length; i++) {
var val = data.registros[i];
var row = $('<tr></tr>');
for(int j = 0; j < val.length; j++) {
row.append($('<td></td>').text(val[j]));
}
results.append(row);
}
}
}
});
});
In addition, you should be testing if the value of the file input is null before making the ajax call (and cancel the ajax call and display the message if it is) to prevent an unnecessary call to the server.

.Net RunTimeBinderException

I have a data content witch contains complex data I just need index names which seem in Dynamic View in data. In debug mode I can see the datas but cant get them..
You can see the contents of data in image below):
if(hits.Count() > 0)
{
var data = hits.FirstOrDefault().Source;
var dataaa = JsonConvert.DeserializeObject(hits.FirstOrDefault().Source);
}
I found a solution with checking if selected index has documents; if yes,
I take the first document in index, and parse it to keys(field names) in client.
here is my func:
[HttpPost]
public ActionResult getIndexFields(string index_name)
{
var node = new Uri("http://localhost:9200");
var settings = new ConnectionSettings(
node,
defaultIndex: index_name
);
var esclient = new ElasticClient(settings);
var Documents = esclient.Search<dynamic>(s => s.Index(index_name).AllTypes().Source());
string fields = "";
if (Documents.Documents.Count() > 0)
{
fields = JsonConvert.SerializeObject(Documents.Documents.FirstOrDefault());
var data = Documents.Documents.FirstOrDefault().Source;
return Json(new
{
result = fields,
Success = true
});
}
return Json(new
{
result = "",
Success = false
});
}
and my js:
$.ajax({
url: "getIndexFields?index_name=" + $(this).val(),
type: "POST",
success: function (data) {
if (data.Success) {
var fields = JSON.parse(data.result);
var fields_arr = [];
$.each(fields, function (value, index) {
fields_arr.push(
{
id: value,
label: value
})
});
options.filters = fields_arr;
var lang = "en";//$(this).val();
var done = function () {
var rules = $b.queryBuilder('getRules');
if (!$.isEmptyObject(rules)) {
options.rules = rules;
}
options.lang_code = lang;
$b.queryBuilder('destroy');
$('#builder').queryBuilder(options);
};
debugger
if ($.fn.queryBuilder.regional[lang] === undefined) {
$.getScript('../dist/i18n/query-builder.' + lang + '.js', done);
}
else {
done();
}
}
else {
event.theme = 'ruby';
event.heading = '<i class=\'fa fa-warning\'></i> Process Failure';
event.message = 'User could not create.';
event.sticky = true;
$("#divfailed").empty();
$("#divfailed").hide();
$("#divfailed").append("<i class='fa fa-warning'></i> " + data.ErrorMessage);
$("#divfailed").show(500);
setTimeout(function () {
$("#divfailed").hide(500);
}, 3000);
}
},
error: function (a, b, c) {
debugger
event.theme = 'ruby';
event.heading = '<i class=\'fa fa-warning\'></i> Process Failure';
event.message = 'Object could not create.';
$("#divfailed").empty();
$("#divfailed").hide();
msg = c !== "" ? c : a.responseText;
$("#divfailed").append("<i class='fa fa-warning'></i> " + msg);
$("#divfailed").show(500);
setTimeout(function () {
$("#divfailed").hide(500);
}, 3000);
}
});

Want to Save Posted Json data to database

I am posting JSON data through AJAX POST as ::
var length = $('.organizer-media').length;
var contents = $('.organizer-media');
var Title;
type == "New" ? Title = $('#newName').val() : Title = $('#Playlist option:selected').text();
var playlistid = $('#Playlist').val()
type == "New" ? playlistid = 0 : playlistid = $('#Playlist').val()
var data = [];
for (var i = 0; i < length; i++) {
data[i] = { ID: parseInt(contents[i].id), MetaID: parseInt(contents[i].title) }
}
var totaldata={ data: data, playlistid: parseInt(playlistid),Title:Title };
$.ajax({
type: 'POST',
data: JSON.Stringify(totaldata),
url: '/Builder/Save',
success: function () {
alert("Playlist saved successfully!!");
}
})
the JSON data is sent in following format::
{"data":[{"ID":779389,"MetaID":774367},{"ID":779390,"MetaID":774367},{"ID":779387,"MetaID":774366},{"ID":779388,"MetaID":774366},{"ID":779386,"MetaID":774365},{"ID":779385,"MetaID":774364},{"ID":779384,"MetaID":774363},{"ID":779383,"MetaID":774362},{"ID":779382,"MetaID":774361},{"ID":779381,"MetaID":774360},{"ID":779378,"MetaID":774359},{"ID":779379,"MetaID":774359},{"ID":779377,"MetaID":774358},{"ID":779376,"MetaID":774357},{"ID":779375,"MetaID":774356},{"ID":779372,"MetaID":774355},{"ID":779373,"MetaID":774355},{"ID":779374,"MetaID":774354},{"ID":779370,"MetaID":774353},{"ID":779394,"MetaID":774370}],"playlistid":1461,"Title":"MX OPEN TALENT MARIA"}:
and as I made an ItemViewModel as ::
public class ItemEditViewModel
{
public long ID { get; set; }
public long MetaID { get; set; }
}
and My controller code is as::
[HttpPost]
public ActionResult Save(ItemEditViewModel[] data,long playlistid=0, string Title="")
{
for (int i = 0; i < data.Length; i++)
{
var pc = db.PlaylistContents.FirstOrDefault(x => x.PlaylistContentId == data[i].ID);
if (pc == null)
{
pc = new PlaylistContent();
db.PlaylistContents.Add(pc);
}
pc.ContentMetaDataId = data[i].MetaID;
pc.PlaylistContentSequenceId = i + 1;
}
db.SaveChanges();
return Json(new { foo = "bar", baz = "Blech" });
}
while Execution of data in controller it doesn't accept the POSTED data as its ViewModel values.
My Problem is solved.
As I have Posted array in combination with two other variables, I just need to stringify array & not the whole ajax data which is to be posted.
as you can see in my code below::
var totaldata = { data: data, playlistid: parseInt(playlistid), Title: Title };
$.ajax({
type: 'POST',
data: { data: JSON.stringify(data), playlistid: parseInt(playlistid), Title: Title, deleted: JSON.stringify(deleted) },
traditional:true,
url: 'Save',
success: function (data) {
alert("Playlist saved successfully!!");
}
})
In above code I have just done stringify on array & not on other data.
Thanks for some Co-operations of yours.

jQuery DatePicker inline highlight certain dates

My problem is that the calendar is rendering before the JSON response is sent to the browser. In other words when we get to the array search my array is empty. How would I fix this?
UPDATED: I gave up on trying to request more dates on month change, so now I just get about 6 months worth of events on my first call and display it all at once. Below is the working code.
$(document).ready(function () {
var actionCalDates = [];
//var orgID = 0;
var currentDate = new Date();
dateCount = 0;
getDates(1, currentDate.getMonth(), currentDate.getFullYear());
function displayCalendar() {
$("#calendar").datepicker({
dateFormat: 'dd/mm/yyyy',
beforeShowDay: function (thedate) {
var theday = (thedate.getMonth() + 1) + "/" + thedate.getDate() + "/" + thedate.getFullYear();
//console.log("Before the if my array contains: " + actionCalDates);
if ($.inArray(theday, actionCalDates) == -1) {
//console.log(theday + " Not Found");
return [false, "", ""];
} else {
//console.log(theday + " Found");
return [true, "specialDate", "Actions Today"];
}
}
});
}
function getDates(orgID, month, year) {
dateCount += 1;
if (dateCount < 4) {
$.ajax({
url: "/Calendar/getEvents",
data: {
'orgID': orgID,
'month': month,
'year': year
},
type: "GET",
dataType: "json",
success: function (result) {
//console.log(result);
for (var i in result) {
actionCalDates.push(result[i]);
//console.log("Pushed to the array: " + actionCalDates[i]);
}
//console.log("Array currently holds: " + actionCalDates);
displayCalendar();
}
});
}
}
});
Code Behind C# controller:
public JsonResult getEvents(int orgID, int month, int year)
{
DateTime orgDate = Convert.ToDateTime(month + "/" + orgID + "/" + year);
var fromDate = orgDate;
var toDate = orgDate.AddMonths(7); //last month and the next 6 months
var events = db.Events.Where(e => e.StartDate >= fromDate && e.EndDate <= toDate).ToArray();
var eventlist = from e in events
select new
{
date = e.StartDate.ToString(),
};
List<string> EventDates = new List<string>();
foreach (var currentEvent in eventlist)
{
DateTime dt;
dt = Convert.ToDateTime(currentEvent.date.ToString());
EventDates.Add(dt.Month + "/" + dt.Day + "/" + dt.Year);
}
return Json(EventDates, JsonRequestBehavior.AllowGet);
}
Why not putting the $("#calendar").datepicker({ call inside the ajax success: handler:
success: function (result) {
console.log(result);
for (var i in result) {
actionCalDates.push(result[i]);
console.log("Pushed to the array: " + actionCalDates[i]);
}
//actionCalDates = actionCalDates.concat(result);
console.log("Array currently holds: " + actionCalDates);
//getDates(orgID, month + 1, year);
//getDates(orgID, month - 1, year);
//Now we have filled the array, let's create our calendar..
$("#calendar").datepicker({
....
}
Put the code that renders the calendar into some arbitrary function, then put a call to that function in your ajax({success: }) function
ie
function renderCalendar(){
$("#calendar").datepicker({
...
});
}
success: function (result) {
...
renderCalendar();
}
I think the method you want is called onChangeMonthYear.
I have used it in a tutorial I wrote up. It's probably not the prettiest code ever written however it does seem to be basically working.

Resources