Before posting this question I tried other related posts but it didn't work out, so posting here.
I have got a Json stored in a hidden field that I am accessing in code behind file of my Mark-up page. I need to convert this Json into List and bind it to a grid, but while de-serializing it throws error saying "Unexpected error encountered while parsing values ''".
Script for getting data from grid and making a Json object.
function BeforeSorting() {
var list = UpdateDataSource();
$("#SortingField").val(list);
}
function UpdateDataSource() {
var list="";
var grid = $find("DetailsGrid");
var rows = grid.get_rows();
for(var i =0 ; i<rows.get_length();i++){
var name = rows.get_row(i).get_cellByColumnKey("Name").get_value();
var country = rows.get_row(i).get_cellByColumnKey("Country").get_value();
var gender = rows.get_row(i).get_cellByColumnKey("Gender").get_value();
var age = rows.get_row(i).get_cellByColumnKey("Age").get_value();
var uniqueKey = rows.get_row(i).get_cellByColumnKey("UniqueKey").get_value();
list = list + '{"Name":"' + name + '", "Country":"' + country + '", "Gender":"' + gender + '", "Age":' + age + ', "UniqueKey":' + uniqueKey + '},';
}
list = "["+list.substr(0, list.length - 1)+"]";
return JSON.parse(list);
}
The model class:
public class Details
{
public string Name { get; set; }
public string Gender { get; set; }
public string Country { get; set; }
public int UniqueKey { get; set; }
public int Age { get; set; }
}
The code for de-serializing the json and retrieving data as a list of the model class.
protected void DetailsGrid_ColumnSorted(object sender, Infragistics.Web.UI.GridControls.SortingEventArgs e)
{
var dataSource = SortingField.Value;
List<Details> result = (List<Details>)Newtonsoft.Json.JsonConvert.DeserializeObject(dataSource, typeof(List<Details>));
DetailsGrid.DataSource = result;
DetailsGrid.DataBind();
}
The json string as obtained:
"[{"Name":"Jerry", "Country":"U.S.A.", "Gender":"Male", "Age":20, "UniqueKey":1},{"Name":"Tom", "Country":"U.K", "Gender":"Male", "Age":10, "UniqueKey":2},{"Name":"George", "Country":"Gremany", "Gender":"Male", "Age":38, "UniqueKey":3},{"Name":"Kate", "Country":"France", "Gender":"Female", "Age":40, "UniqueKey":4},{"Name":"Jenny", "Country":"Poland", "Gender":"Female", "Age":25, "UniqueKey":5}]"
create list as an array and add items as JavaScript objects and then convert it to JSON using JSON.stringify
function UpdateDataSource() {
var grid = $find("DetailsGrid");
var rows = grid.get_rows();
var list = [];
for(var i =0 ; i < rows.get_length(); i++){
var item = {
Name : rows.get_row(i).get_cellByColumnKey("Name").get_value(),
Country : rows.get_row(i).get_cellByColumnKey("Country").get_value(),
Gender : rows.get_row(i).get_cellByColumnKey("Gender").get_value(),
Age : rows.get_row(i).get_cellByColumnKey("Age").get_value(),
UniqueKey : rows.get_row(i).get_cellByColumnKey("UniqueKey").get_value()
};
list.push(item);
}
return JSON.stringify(list);
}
The code for de-serializing the json and retrieving data as a list of the model class can be refactored to
protected void DetailsGrid_ColumnSorted(object sender, Infragistics.Web.UI.GridControls.SortingEventArgs e) {
var dataSource = SortingField.Value;
var result = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Details>>(dataSource);
DetailsGrid.DataSource = result;
DetailsGrid.DataBind();
}
UPDATE as suggested by #Adnreas should produce the same result.
function UpdateDataSource() {
var grid = $find("DetailsGrid");
var rows = grid.get_rows();
var list = rows.map(function(row) {
return {
Name: row.get_cellByColumnKey("Name").get_value(),
Country: row.get_cellByColumnKey("Country").get_value(),
Gender: row.get_cellByColumnKey("Gender").get_value(),
Age: row.get_cellByColumnKey("Age").get_value(),
UniqueKey: row.get_cellByColumnKey("UniqueKey").get_value()
};
});
return JSON.stringify(list);
}
I think this will do
protected void DetailsGrid_ColumnSorted(object sender, Infragistics.Web.UI.GridControls.SortingEventArgs e)
{
var dataSource = SortingField.Value;
List<Details> result = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Details>>(dataSource);
DetailsGrid.DataSource = result;
DetailsGrid.DataBind();
}
Related
I have two text boxes that are enabled based on a checkbox. If checked == true then enable editing. Until this point everything is fine. However, when I hit the Submit button to save it to the database, it's not working. I was able to save it with just one of the text boxes being editable. Now that I have two editable boxes, it's not working.
Problem:
The ajax call is sending the dates and the ID back to the controller method. However, it's not getting saved to the DB. In UpdatePlannedDate I put in a couple breakpoints, its completely skipping over the first forEach loop.
The Exception it's throwing:
String was not recognized as a valid DateTime.
Model Class:
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? Date1{ get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? Date2{ get; set; }
public string R_ID { get; set; }
public string U_ID { get; set; }
public string C_ID { get; set; }
Controller class:
[HttpPost]
public JsonResult UpdatePlannedDate(string ids, string Date1, string Date2)
{
model = new Hello();
Entity db = new Entity();
List<Hello> list = new List<Hello>();
string[] IDS = ids.Split(',');
string[] Date1S = Date1.Split(',');
string[] Date2S = Date2.Split(',');
try
{
for (int i = 0; i < IDS.Length; i++)
{
if (IDS[i] != null && IDS[i] != "")
{
Hello item = new Hello { R_ID = IDS[i], Date_Two = DateTime.Parse(Date2S[i]), Date_One = DateTime.Parse(Date1S[i]) };
list.Add(item);
}
}
foreach (var row in db.table1)
{
foreach (var row2 in db.table2)
{
if (row.U_ID == row2.C_ID)
{
foreach (var item in list)
{
if (row.U_ID == item.R_ID)
{
var cd = db.Table2.Where(x => x.C_ID == row.U_ID).First();
cd.PlanDate = Convert.ToDateTime(item.Date_Two);
cd.PlanDate = Convert.ToDateTime(item.Date_One);
}
}
}
}
}
db.SaveChanges();
return Json(new { success = true, msg = "Updated" });
}
catch (Exception ex)
{
return Json(new { success = false, msg = ex.Message });
}
}
View class:
$(document).ready(function () {
var ids = "";
var date1 = "";
var date2 = "";
//Save to DB
$("#btnSubmit").bind("click", function () {
createUpdateArrays();
var url = "/Sample/UpdatePlannedDate";
$.ajax({
type: "POST",
url: url,
data: { ids: ids, date1: date1, date2: date2 },
success: function (data) {
if (data.success) {
$('.msg').html('Updated');
}
else {
alert("error");
}
}
});
ids = "";
date1 = "";
date2 = "";
});
function createUpdateArrays() {
var i = 0;
$('input.remedy-id:checkbox').each(function () {
if ($(this).is(':checked')) {
var rid = $(this).attr("id");
$('.date2').each(function () {
var did = $(this).attr("id");
if (did === rid) {
var date_2 = $(this).val();
ids += rid + ",";
date2 += date_2 + ",";
}
});
$('.date1').each(function () {
var tid = $(this).attr("id");
if (tid === rid) {
var date_1 = $(this).val();
ids += rid + ",";
date1 += date_1 + ",";
}
});
};
});
};
<tr id="home">
<td><input class="id" type="checkbox" id=#item.R_ID/></td>
<td>#Html.DisplayFor(x => item.R_ID)</td>
<td><input class="date1" id=#item.R_ID type="text" value='#(item.Date1 == null ? "" : Convert.ToDateTime(item.Date1).ToString("MM/dd/yyy"))' readonly="readonly" /></td>
<td><input class="date2" id=#item.R_ID type="text" value='#(item.Date2 == null ? "" : Convert.ToDateTime(item.Date2).ToString("MM/dd/yyy"))' readonly="readonly" /></td>
</tr>
1) What is your ORM? Entity Framework?
2) Try to debug line:
Hello item = new Hello { R_ID = IDS[i], Date_Two = DateTime.Parse(Date2S[i]), Date_One = DateTime.Parse(Date1S[i]) };
3) Isn't datetime conversion twice there?
First Hello item = ... line, second there
cd.PlanDate = Convert.ToDateTime(item.Date_Two);
cd.PlanDate = Convert.ToDateTime(item.Date_One);
4) What will do the change:
cd.PlanDate = item.Date_Two;
cd.PlanDate = item.Date_One;
?
5) Isn't also a logical fault there to have assignation of 2 values to one variable here?
6) Do you have any javascript extension to your fields on side of Razor template? What format it will produce here if you will pick your time from calendar? Does it fits to your definition mask in model class? (
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
)
The data is passed from the controller to the view using AJAX call
but for some reason I am not able to retrieve it using JavaScript
the data shows an list on empty object!
public class Ville {
string wilPop { get; set; }// = null;
int identifiant { get; set; }// = -1;
bool affectedD { get; set; } //= false;
public Ville(string ewilPop, int eidentifiant, bool eaffectedD)
{
this.wilPop = ewilPop;
this.identifiant = eidentifiant;
this.affectedD = eaffectedD;
}
}
[Authorize]
[HttpPost]
public ActionResult GetWilByRegion(int? Wil)
{
if (Wil != null)
{
string wilPop = null;
int identifiant = -1;
bool affectedD = false;
//Get info from DB
List<city> ListWil = new List<city>();
ListWil = db.city.Where(m => m.idReg == Wil).OrderByDescending(m => m.population).ToList();
List<Ville> mylist = new List<Ville>();
foreach (city item in ListWil)
{
// Description in the DB
wilPop = item.city + " (" + item.population + ")";
// id value in the DB
identifiant = item.city_id;
// if checked or not
affectedD = CheckifWilAffected(item.city_id);
mylist.Add(new Ville(wilPop, identifiant, affectedD));
}
return Json(mylist, "Ville");
}
else return Json("Error");
}
mylist is not empty, it contains all the data (after debugging the controller)
This is my AJAX call :
$.ajax({
url: url,
data: { Wil: _idr },
cache: false,
type: "POST",
success: function (data) {
var markup = "";
for (var x = 0; x < data.length; x++) {
markup += '<input type=' + '"checkbox"' + ' name=' + data[x].wilPop + ' value=' + data[x].identifiant + '>' + data[x].wilPop + '</input>' + '<br/>';
}
$("#chWil").html(markup).show();
},
error: function () {
alert("Error - can't do the ajax call - please check your code..." );
}
});
}
You are getting an array of empty objects(without any properties) because your Ville class does not have any public properties.
You need to make your properties public
public class Ville
{
public string wilPop { get; set; }
public int identifiant { get; set; }
public bool affectedD { get; set; }
public Ville(string ewilPop, int eidentifiant, bool eaffectedD)
{
this.wilPop = ewilPop;
this.identifiant = eidentifiant;
this.affectedD = eaffectedD;
}
}
Now the JavaScript serializer will be able to use the values of those properties when creating a JSON string representation of your list.
I personally like to use PascalCasing for class property names.( WilPop instead of wilPop)
I am working to send multiple email/SMS by selecting the checkbox. And When I am receiving in my javascript function it's getting with data. But when I pass it to action method record count shows but all data are null. Below is my code with screenshot here
Here it is my Model:
public class BulkEmailSendViewModel
{
public BulkEmailSendViewModel()
{
Candidates = new List<CandidateData>();
}
public List<CandidateData> Candidates { get; set; }
public string Body { get; set; }
public string Subject { get; set; }
}
public class CandidateData
{
public string Email { get; set; }
public string CandidateId { get; set; }
public string Phone { get; set; }
public string CandidateName { get; internal set; }
}
//Select all selected checkbox
$("#bulkAction").change(function () {
var ddlId = $("#bulkAction").val();//to get sms or email
var chk_arr = $('.checkCandidate:checkbox:checked');
var chklength = chk_arr.length;
var json = '';
$('.checkCandidate:checkbox:checked').each(function () {
if (this.checked) {
var Phone = $(this).attr("candidatePhone");
var CandidateId = $(this).attr("candidateId");
var Email = $(this).attr("candidatEmail");
var item = '{\"Phone\":\"' + Phone + '\","CandidateId\":\"' + CandidateId + '\",\"Email\":\"' + Email + '\",\"CandidateName\":\"\"},';
json += item;
}
});
json = "[" + json.substr(0, json.length - 1) + "]";
SendBulkEmail(json);
});
My Javascript:
function SendBulkEmail(jsonObj) {
alert(jsonObj);
if (jsonObj.length > 0) {
var send = "/Utility/Notifications/BulkEmail";
$(".modal-title").text("Send Email");
//var data = {
// Candidates: eval(jsonObj)
//};
$.get(send, { bulkEmailSendViewModel: eval(jsonObj) }, function (result) {
$("#C_modal_body").html("");
$("#C_modal_body").html(result);
});
}
else {
$.alert("Email not found for this candidate.");
// e.stopPropagation();
}
}
My Controller:
public PartialViewResult BulkEmail(List<CandidateData> bulkEmailSendViewModel)
{
BulkEmailSendViewModel bulkDetail = new BulkEmailSendViewModel();
return PartialView(bulkDetail);
}
Why my all values are null even I am getting in javascript function?
change your javascript codes to this:
$("#bulkAction").change(function () {
var ddlId = $("#bulkAction").val();//to get sms or email
var chk_arr = $('.checkCandidate:checkbox:checked');
var chklength = chk_arr.length;
var data = [];
$('.checkCandidate:checkbox:checked').each(function () {
if (this.checked) {
var Phone = $(this).attr("candidatePhone");
var CandidateId = $(this).attr("candidateId");
var Email = $(this).attr("candidatEmail");
var item = {Phone: Phone,
CandidateId: CandidateId,
Email : Email,
CandidateName : ""};
data.push(item);
}
});
SendBulkEmail(data);
});
and the SendBulkEmail to:
function SendBulkEmail(data) {
if (data.length > 0) {
var send = "/Utility/Notifications/BulkEmail";
$(".modal-title").text("Send Email");
//var data = {
// Candidates: eval(jsonObj)
//};
$.post(send, { bulkEmailSendViewModel: JSON.stringify(data) }, function (result) {
$("#C_modal_body").html("");
$("#C_modal_body").html(result);
});
}
else {
$.alert("Email not found for this candidate.");
// e.stopPropagation();
}
}
and finally:
[HttpPost]
public PartialViewResult BulkEmail(List<CandidateData> bulkEmailSendViewModel)
{
BulkEmailSendViewModel bulkDetail = new BulkEmailSendViewModel();
return PartialView(bulkDetail);
}
In your controller, I don't see any use of the bulkEmailSendViewModel input parameter.
Maybe, you could propagate the candidate list as follow:
public PartialViewResult BulkEmail(List<CandidateData> candidates)
{
BulkEmailSendViewModel bulkDetail=new BulkEmailSendViewModel();
bulkDetail.candidates = candidates;
return PartialView(bulkDetail);
}
I have a Web-API method that is returning JSON and I want the array structure to look like this:
[ [123, 1.1], [222, 3.9] ]
My Web API controller is returning JSON in the following format:
[{"CreatedDate":1314736440,"Reading":20.0}, "CreatedDate":1314779640,"Reading":7.9}]
Web API Controller:
[HttpGet]
public HttpResponseMessage AllJson()
{
using (var ctx = new SomeContext())
{
var records = ctx.DataX.ToList();
var dtos = Mapper.Map<...>(records);
return new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonConvert.SerializeObject(dtos), Encoding.UTF8, "application/json")
};
}
}
DTO
public class DtoModel
{
public int CreatedDate { get; set; }
public double Reading { get; set; }
}
Sample Javascipt:
var seriesData = [];
$.getJSON("api/xxx/AllJson ", function (data) {
$.each(data, function (key, val) {
seriesData.push(val.CreatedDate.toString() + " ," + val.Reading.toString());
console.log(val.CreatedDate + " ," + val.Reading);
});
});
You need to create an a single array containing many arrays of length 2.
See this code:
$.getJSON("api/xxx/AllJson")
.done(function (data) {
var processedJson = new Array();
$.map(data, function (obj, i) {
processedJson.push([obj.CreatedDate, obj.Reading]);
});
FunctionToDoSomethingWithYourDataStructure(processedJson);
});
I think this might solve your problem..
structure wise, this should look like [[a,b],[c,d]];
var createSeriesData = function(){
seriesData = [];
JSON_obj = JSON.parse('[{"CreatedDate":1314736440,"Reading":20.0},{"CreatedDate":1314779640,"Reading":7.9}]');
for(var key in JSON_obj){
if(JSON_obj.hasOwnProperty(key)){
seriesData[key] = [];
seriesData[key].push(JSON_obj[key].CreatedDate.toString());
seriesData[key].push(JSON_obj[key].Reading.toString());
}
}
console.log(seriesData);
}
I have a Model like this in my ASP.NET MVC 2 project,
public class HomeModel
{
public string Name { get; set; }
public int HomeCount { get; set; }
private List<string> _list;
public List<string> List
{
get
{
if (_list == null)
{
_list = new List<string>();
}
return _list;
}
set
{
_list = value;
}
}
private List<ChildModel> _children;
public List<ChildModel> Children
{
get
{
if (_children == null)
{
_children = new List<ChildModel>();
}
return _children;
}
set
{
_children = value;
}
}
}
public class ChildModel
{
public string Address { get; set; }
}
and the script as
var obj = new Object();
obj.Name = "MyName";
obj.HomeCount = 56;
obj.List = new Array();
obj.List[0] = "AAA";
obj.List[1] = "bbb";
var child = new Object();
child.Address = "ccc";
obj.Children = new Array();
obj.Children[0] = child;
var child2 = new Object();
child.Address = "ddd";
obj.Children[1] = child2;
jQuery.ajaxSettings.traditional = true
$.post('/Home/Test',obj, function (data) { });
My problem is even the string list is generated at the controller's action, the object list's count is 0. Can anyone tell how to do this?
When you submit an object as jQuery's ajax payload, it's converted to key/value pairs of data. If this were $.get instead of $.post for example, you'd wind up with
?name=MyName&etc.
This article should get you what you're looking for:
http://www.intelligrape.com/blog/2010/06/11/jquery-send-json-object-with-an-ajax-request/
I'd also recommend json/object literal notation here:
var obj = {
Name: "MyName",
HomeCount: 56,
List:["AAA","bbb"],
child:{
Address: "ccc",
Children:[
//etc
]
}
}
see json.org for specs, and jslint.com/jshint.com for validation.