Kendo ListView populating with undefined data - json

My KendoListView populates the correct number of items but does not populate the fields correctly. The data is being passed in from my controller as a JSON result and I am getting the correctly number of items in my list view but the template renders "Member: undefined undefined". The strange thing is that this is almost a one-to-one copy and paste from a similar view I have and it works fine.
ListView code:
#section head
{
<script type="text/javascript">
var dataSource;
$(document).ready(function () {
dataSource = new kendo.data.DataSource({
schema: {
data: "Data",
total: "Total",
model: {
fields: {
MemberID: { editable: false, nullable: false },
FirstName: { editable: false, nullable: false },
LastName: { editable: false, nullable: false }
}
}
},
transport: {
read: {
url: "#Url.Action("GetMembers", "Pages", new { area = "Admin" })",
contentType: "application/json",
type: "POST"
}
}
});
$("#memberList").kendoListView({
autoBind: false,
dataBound: function (e) {
if (dataSource.total() == 0) {
$("#MemberList").html('<tr><td>There are no members at this time.</td></tr>');
};
},
dataSource: dataSource,
template: kendo.template($("#memberTemplate").html())
});
dataSource.read();
});
</script>
}
<script type="text/x-kendo-template" id="memberTemplate">
<tr>
<td style="padding-right:10px;padding-left:10px">
Member: #= FirstName # #= LastName #
</td>
</tr>
</script>
<div>
<table>
<tbody id="memberList"></tbody>
</table>
</div>
The model schema that is passed in:
string Address1
string Address2
string Address3
bool BeLeader
string City
string EmailAddress
string FirstName
string LastName
Guid MemberID
string PhoneNumber
bool ReceiveEmails
Guid StateID
string Zip
Update: My Controller method is returning the correctly number of arrays but they are blank...not sure why. Here's my constroller code:
[Authorize]
[HttpPost]
public JsonResult GetMembers([DataSourceRequest]DataSourceRequest request)
{
List<Member> results = new List<Member>();
try
{
results = adminServices.GetMembers();
}
catch
{
}
JsonResult test = Json(results.ToDataSourceResult(request));
return Json(results.ToDataSourceResult(request));
}

Related

AngularJS passing Json to controller and displaying in a DevExpress Chart

I have a JsonResult method in my controller. I have pulled in data from my database and set to an object. The method will return this object. I am trying pass this data into AngularJS data source. I would like to display a DevExtreme bar chart. Here is code so far.
AngularJS file:
var app = angular.module('customApp', ['dx']);
app.controller("chartControl", function ($scope, $http) {
$scope.sizeSettings = {
dataSource: 'http://localhost:53640/Home/PostChart',
commonSeriesSettings: {
argumentField: 'product_id',
valueField: "product_id", name: "Product Cost",
type: "bar"
},
seriesTemplate: {
nameField: 'Source',
}
};
});
Home Controller:
public JsonResult PostChart(int product_id)
{
Object prod = null;
using (ProductOrderEntities db = new ProductOrderEntities())
{
var product = db.Products.FirstOrDefault(p => p.product_id == product_id);
prod = new {productID = product.product_id, productName = product.product_name, productPrice = product.product_cost, productDescription = product.product_type};
}
return Json(prod, JsonRequestBehavior.AllowGet);
}
}
HTML
<div ng-app="customApp">
<div ng-controller="chartControl">
</div>
</div>
Seems like you forget add markup for chart:
<div dx-chart="chartOptions"></div>
I've made a simple ASP.NET MVC application here https://www.dropbox.com/s/hk3viceoa2zkyng/DevExtremeChart.zip?dl=0
Open the start page http://localhost:56158/Default1/ to see chart in action.
See more information about using DevExtreme Charts in AngularJS app here http://js.devexpress.com/Documentation/Howto/Data_Visualization/Basics/Create_a_Widget/?version=14_2#Data_Visualization_Basics_Create_a_Widget_Add_a_Widget_AngularJS_Approach
This is how I solved it.
HTML
<div ng-app="customCharts">
<div ng-controller="ChartController">
<div dx-chart="productSettings"></div>
</div>
</div>
AngularJS
var app = angular.module('customCharts', ['dx']);
app.controller("ChartController", function ($scope, $http, $q) {
$scope.productSettings = {
dataSource: new DevExpress.data.DataSource({
load: function () {
var def = $.Deferred();
$http({
method: 'GET',
url: 'http://localhost:53640/Home/PostChart'
}).success(function (data) {
def.resolve(data);
});
return def.promise();
}
}),
series: {
title: 'Displays Product Costs for items in our Database',
argumentType: String,
argumentField: "Name",
valueField: "Cost",
type: "bar",
color: '#008B8B'
},
commonAxisSettings: {
visible: true,
color: 'black',
width: 2
},
argumentAxis: {
title: 'Items in Product Store Database'
},
valueAxis: {
title: 'Dollor Amount'
}
}
})
Controller
public JsonResult PostChart()
{
var prod = new List<Object>();
using (ProductOrderEntities db = new ProductOrderEntities())
{
var product = db.Products.ToList();
foreach (var p in product)
{
var thing = new { Name = p.product_name, Cost = p.product_cost };
prod.Add(thing);
}
}
return Json(prod, JsonRequestBehavior.AllowGet);
}

Pass data from controller to view via JSONResult

I'd like to send ViewModel from controller to view in JSON format.
Controller:
public ActionResult Select(int pageLimiter)
{
var viewModel = new ArticlesViewModel
{
Articles = this.Service.GetArticles(0, 0, 0),
ArticlesTotal = this.Service.CountArticles(0),
Pages = new List<string>
{
"1", "2", "3"
}
};
return Json(viewModel, JsonRequestBehavior.AllowGet);
}
View:
<ul class="articleList">
#if (#Model != null)
{
foreach (var article in #Model.Articles)
{
<li>
<header>#article.Title</header>
<nav>
<span>#article.AuthorName</span> |
<time>#article.PublishDate.ToString("")</time> |
<span>#article.CategoryName</span> |
<span>#article.Comments Comments</span>
</nav>
<section>
#article.Content
</section>
</li>
}
}
</ul>
<script type="text/javascript">
$(document).ready(function () {
GetArticles(5);
$("#selectPager").change(function () {
var selectedItem = "";
$("#selectPager option:selected").each(function () {
selectedItem = $(this).text();
});
GetArticles(selectedItem);
});
});
function GetArticles(pageLimitValue) {
$.ajax(
{
url: "/Articles/Select",
dataType: "json",
data: { pageLimiter: pageLimitValue },
async: true,
beforeSend: function () {
alert("before");
},
complete: function (data) {
#Model = SOME_MAGIC_TRICKS
}
});
}
As you can see, in the complete event are words SOME_MAGIC_TRICKS. In this place I'd like to set #Model obtained from controller. Is it possible at all? How to insert data from ajax result to view model (it's null by default)?
You are trying to modify server variable from client's code. It's not possible.
If you want to re-render your page's content on complete, you may render <ul class="articleList"> with PartialView and return same partial view instead of JsonResult. Further, oncomplete handler will update your <ul class="articleList"> with returned content.
You can send data doing serialize it may be like:
public ActionResult Select(int pageLimiter)
{
var viewModel = new ArticlesViewModel
{
Articles = this.Service.GetArticles(0, 0, 0),
ArticlesTotal = this.Service.CountArticles(0),
Pages = new List<string>
{
"1", "2", "3"
}
};
string myjsonmodel = new JavaScriptSerializer().Serialize(viewModel );
return Json(jsonmodel = viewModel, JsonRequestBehavior.AllowGet);
}
dont forget using using System.Web.Script.Serialization;
Edit:
To deserialize object try this:
#{
JavaScriptSerializer jss= new JavaScriptSerializer();
User user = jss.Deserialize<User>(jsonResponse);
}

JqGrid trying to send large data from server to grid but getting:Error during serialization or deserialization using the JSON JavaScriptSerializer

I have a problem I am receiving large amount of data from the server and am then converting it to Json format, to be then viewed in JqGrid. It works for small amount of data say for example 200 rows but when doing this for 10000 rows it throws the following error
System.InvalidOperationException: Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property
I have tried using the javascript serializer and set it to maxjsonLenght = int32.MaxValue but still no luck
Following is my code please give me suggestions with examples how I can fix this? Thanks all!
GridConfig
public JqGridConfig(String db, String jobGroup, String jobName, String detailTable, String filterBatchControl, String filterDate, String filterTime, int page)
{
var entityhelper = new EntityHelper();
var s = new JsonSerializer();
try
{
//Populate Grid Model, Column Names, Grid Column Model, Grid Data
entityhelper.PopulateDetailGridInit(db, jobGroup, jobName, detailTable, filterBatchControl, filterDate, filterTime);
JqGridDetailAttributes = entityhelper.GridDetailAttributes;
JqGridDetailColumnNames = entityhelper.GridDetailColumnNames;
//JqGridDetailsColumnNamesForExport = entityhelper.GridDetailColumnNamesForExport;
JqGridDetailColumnModel = entityhelper.GridDetailColumnModel;
//Dynamic Data
JqGridDynamicDetailData = entityhelper.GridDetailData;
#region Column Model
foreach (KeyValuePair<String, JqGridColModel> kvp in entityhelper.GridDetailColumnModel)
{
s.Serialize(kvp.Key, kvp.Value.Attributes);
}
JqGridDetailColumnModelJson = s.Json();
#endregion
#region Concrete data. 1. List<dynamic> populated, 2. Convert to Json String, 3: Convert back to List<Detail>
JqGridDetailData = JsonSerializer.ConvertDynamicDetailsToJson(JqGridDynamicDetailData); // this is where the error occurs
}
catch (Exception ex)
{
//TODO: Logging
System.Diagnostics.Debug.WriteLine(ex.Message);
}
}
Json Serializer
public static IList<Detail> ConvertDynamicDetailsToJson(IList<dynamic> list)
{
if (list.Count == 0)
return new List<Detail>();
var sb = new StringBuilder();
var contents = new List<String>();
sb.Append("[");
foreach (var item in list)
{
var d = item as IDictionary<String, Object>;
sb.Append("{");
foreach (KeyValuePair<String, Object> kvp in d)
{
contents.Add(String.Format("{0}: {1}", "\"" + kvp.Key + "\"", JsonConvert.SerializeObject(kvp.Value)));
}
sb.Append(String.Join(",", contents.ToArray()));
sb.Append("},");
}
sb.Append("]");
//remove trailing comma
sb.Remove(sb.Length - 2, 1);
var jarray = JsonConvert.DeserializeObject<List<Detail>>(sb.ToString());
return jarray;
}
Controller that return Json result from server
public JsonResult DetailGridData(TheParams param)
{
dynamic config= "";
switch (param.JobGroup)
{
case "a":
config = new BLL.abcBLL().GetDetailGridData("rid", "desc", 1, 20, null,
param.FilterBatchControl,
param.JobName, param.DetailTable,
param.JobGroup, param.BatchDate,
param.Source);
break;
}
return Json(config, JsonRequestBehavior.AllowGet); // this reurns successfully json result
}
View where the Jqgrid exists and does not populate the grid
<script type="text/javascript">
var jobGroup = '#ViewBag.JobGroup';
var jobName = '#ViewBag.JobName';
var detailTable = '#ViewBag.DetailTable';
var filterBatchControl = '#ViewBag.FilterBatchControl';
var controlDate = '#ViewBag.ControlDate';
var controlTime = '#ViewBag.ControlTime';
var source = '#ViewBag.DetailSource';
var page = '#ViewBag.page';
function loadDetailData() {
var param = new Object();
param.BatchDate = controlDate;
param.BatchTime = controlTime;
param.JobGroup = jobGroup;
param.JobName = jobName;
param.DetailTable = detailTable;
param.FilterBatchControl = filterBatchControl;
param.Source = source;
param.page = page;
window.parent.loadingDetailsHeader();
$.ajax({
url: "/control/detailgriddata",
dataType: 'json',
type: 'POST',
data: param,
async: false,
success: function (response) {
try {
jgGridDetailColumnNames = response.JqGridDetailColumnNames;
//jqGridDetailColumnData = response.JqGridDetailData;
jqGridDetailColumnData = response.config;
$('#detailGrid').jqGrid('setGridParam', {colNames: jgGridDetailColumnNames});
$('#detailGrid').jqGrid('setGridParam', {data: jqGridDetailColumnData}).trigger('reloadGrid');
parent.loadingDetailsHeaderComplete();
}
catch(e) {
window.parent.loadingDetailsHeaderException(e.Message);
}
return false;
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
}
function exportdetails(date) {
var param = new Object();
param.db = source;
param.jobGroup = jobGroup;
param.jobName = jobName;
param.detailTable = detailTable;
param.filterBatchControl = filterBatchControl;
param.filterDate = date;
param.filterTime = "NULL";
$.ajax({
type: 'POST',
contentType: 'application/json; charset=utf-8',
url: '#Url.Action("ExportDetailsCsv", "Control")',
dataType: 'json',
data: $.toJSON(param),
async: false,
success: function (response) {
window.location.assign(response.fileName);
},
error: function (xhr, ajaxOptions, thrownError) {
alert("Details Export Exception: " + xhr.status);
}
});
}
//<![CDATA[
$(document).ready(function () {
'use strict';
$(window).resize(function () {
$("#detailGrid").setGridWidth($(window).width());
}).trigger('resize');
var dgrid = $("#detailGrid");
$('#detailGrid').jqGrid('clearGridData');
loadDetailData();
dgrid.jqGrid({
datatype: 'json',
data: jqGridDetailColumnData,
colNames: jgGridDetailColumnNames,
colModel: [ #Html.Raw(#ViewBag.ColModelDetail) ],
rowNum: 25,
rowList: [25, 50, 100],
pager: '#detailPager',
gridview: true,
autoencode: false,
ignoreCase: true,
viewrecords: true,
altrows: false,
autowidth: true,
shrinkToFit: true,
headertitles: true,
hoverrows: true,
height: 300,
onSelectRow: function (rowId) {
//This is a demo dialog with a jqGrid embedded
//use this as the base for viewing detail data of details
//$('#dialogGrid').dialog();
//gridDialog();
},
loadComplete: function (data) {},
gridComplete: function (data) {
//if (parseInt(data.records,10) < 50) {
$('#detailPager').show();
//} else {
//$('#detailPager').show();
//}
}
}).jqGrid('navGrid', '#detailPager', { edit: false, add: false, del: false, search: false }, {});
});
//]]>
</script>
<table id="detailGrid">
<tr>
<td />
</tr>
</table>
<div id="detailPager"></div>
<div id="dialogGrid"></div>
Probably you should consider to use server side paging instead of returning 10000 rows to the client? Server side paging of SQL data can be implemented much more effectively as client side paging (sorting of large non-indexed data in JavaScript program).
One more option which you have is the usage of another JSON serializer. For example it can be protobuf-net, ServiceStack.Text (see here too), Json.NET and other. In the way you can additionally improve performance of your application comparing with JavaScriptSerializer.

problem with Toolbar Paging Extjs 4&Json

I'm using ExtJS4 to develop some rich interfaces. I'm a beginner with ExtJS and I i have some problems. I have 100 records and I want to show 20 records per page. I have done this code, but its only showing 20 recording in all pages. I have verified in firebug if I have all my data: I have only 20 and my Total is equal to 100. I need help please.
Webservice page:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[ScriptService]
public class Service : System.Web.Services.WebService
{
public class DataGridSource
{
public List<MyDvpt> maListe = new List<MyDvpt>();
private int _total;
public int Total
{
get { return _total; }
set { _total = value; }
}
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = true, XmlSerializeString = false)]
public DataGridSource GetMyDvpt3(int pageSize, int pageNumber)
{
string connectionString = "Data source=DARWIN;Initial Catalog=AGREO_DVPT;User ID=temp;Password=pmet";
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand("SELECT TOP 100 E.NOM_EXP,ESP.NOM_ESP,V.NOM_VAR,P.SURF_PG,P.DD_CYCLE_PROD from gc.PG P inner join ADM.EXP E on E.ID_EXP = P.ID_EXP inner join GC.VAR V on V.ID_VAR = P.ID_VAR inner join GC.ESP ESP on ESP.ID_ESP = V.ID_ESP", connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
List<MyDvpt> list1 = new List<MyDvpt>();
while (reader.Read())
{
MyDvpt dev = new MyDvpt();
dev.NOM_EXP = reader[0].ToString();
dev.NOM_ESP = reader[1].ToString();
dev.NOM_VAR = reader[2].ToString();
dev.SURF_PG = reader[3].ToString();
dev.DD_CYCLE_PROD = reader[4].ToString();
list1.Add(dev);
}
return new DataGridSource { maListe = list1.Skip(pageSize * pageNumber).Take(pageSize).ToList<MyDvpt>(), Total = list1.Count };
}
public class MyDvpt
{
public string NOM_EXP { get; set; }
public string NOM_ESP { get; set; }
public string NOM_VAR { get; set; }
public string SURF_PG { get; set; }
public string DD_CYCLE_PROD { get; set; }
private string _total;
public string Total
{
get { return _total; }
set { _total = value; }
}
}
}
JS page:
function onReady() {
store = new Ext.data.JsonStore({
autoLoad: true,
pageSize: 20,
pageNumber: 1,
groupField: 'NOM_VAR',
proxy: ({
type: 'ajax',
url: '../Service.asmx/GetMyDvpt3?pageSize=20 &pageNumber=1',
reader: {
type: 'json',
root: 'd.maListe',
totalProperty: 'd.Total'
},
headers: {
'Content-type': 'application/json'
}
}),
fields: ['NOM_EXP', 'NOM_ESP', 'NOM_VAR', 'SURF_PG', 'DD_CYCLE_PROD']
});
store.loadPage(1);
var groupingFeature = Ext.create('Ext.grid.feature.Grouping', {
groupHeaderTpl: 'NOM_VAR: {NOM_ESP} ({rows.length} enregistrement{[values.rows.length > 1 ? "s" : ""]})'
});
Ext.create('Ext.grid.Panel', {
store: store,
id:'grid',
collapsible: true,
frame: true,
iconCls: 'icon-grid',
features: [groupingFeature],
columnLines: true,
columns: [
{ dataIndex: 'NOM_EXP', header: 'NOM_EXP', flex: 1 },
{ dataIndex: 'NOM_ESP', header: 'NOM_ESP', flex: 1 },
{ dataIndex: 'NOM_VAR', header: 'NOM_VAR', flex: 1 },
{ dataIndex: 'SURF_PG', header: 'SURF_PG', flex: 1 },
{ dataIndex: 'DD_CYCLE_PROD', header: 'DD_CYCLE_PROD', flex: 1 }
],
fbar: ['->', {
text: 'Clear Grouping',
iconCls: 'icon-clear-group',
handler: function () {
groupingFeature.disable();
}
}],
renderTo: 'panel',
viewConfig: {
stripeRows: true
},
title: 'Dvpt Grid',
width: 1220,
height: 500,
dockedItems: [{
xtype: 'pagingtoolbar',
store: store,
dock: 'bottom',
displayInfo: true
}]
});
}
store.load() response in firebug:
GET http://localhost:1508/Service.asmx/GetMyDvpt3?pa...22NOM_VAR%22%2C%22direction%22%3A%22ASC%22%7D%5D
{"d":{"_type":"MaquetteExtJs.Service+DataGridSource","maListe":[{"_type":"MaquetteExtJs.Service+MyDvpt","NOM_EXP":"DECKERT","NOM_ESP":"Blé Dur Hiver","NOM_VAR":"AMBRAL","SURF_PG":"30000","DD_CYCLE_PROD":"26/02/2003 00:00:00","Total":null},
...
{"__type":"MaquetteExtJs.Service+MyDvpt","NOM_EXP":"DECKERT","NOM_ESP":"Blé Dur Hiver","NOM_VAR":"SOLDUR","SURF_PG":"25000","DD_CYCLE_PROD":"06/03/2002 00:00:00","Total":null}],"Total":"100"}}
d Object { __type="MaquetteExtJs.Service+DataGridSource", maListe=[20], Total="100"}
Currently your response is like this...
{"d":{"_type":"MaquetteExtJs.Service+DataGridSource","maListe":[{"_type":"MaquetteExtJs.Service+MyDvpt","NOM_EXP":"DECKERT","NOM_ESP":"Blé Dur Hiver","NOM_VAR":"AMBRAL","SURF_PG":"30000","DD_CYCLE_PROD":"26/02/2003 00:00:00","Total":null}, ... {"__type":"MaquetteExtJs.Service+MyDvpt","NOM_EXP":"DECKERT","NOM_ESP":"Blé Dur Hiver","NOM_VAR":"SOLDUR","SURF_PG":"25000","DD_CYCLE_PROD":"06/03/2002 00:00:00","Total":null}],"Total":"100"}}
But it should be like this...
{"_type":"MaquetteExtJs.Service+DataGridSource","maListe":[{"_type":"MaquetteExtJs.Service+MyDvpt","NOM_EXP":"DECKERT","NOM_ESP":"Blé Dur Hiver","NOM_VAR":"AMBRAL","SURF_PG":"30000","DD_CYCLE_PROD":"26/02/2003 00:00:00","Total":null}, ... {"__type":"MaquetteExtJs.Service+MyDvpt","NOM_EXP":"DECKERT","NOM_ESP":"Blé Dur Hiver","NOM_VAR":"SOLDUR","SURF_PG":"25000","DD_CYCLE_PROD":"06/03/2002 00:00:00","Total":null}],"Total":"100"}
Also you need to update your JsonReader config in your JsonStore..
proxy: ({
type: 'ajax',
url: '../Service.asmx/GetMyDvpt3?pageSize=20 &pageNumber=1',
reader: {
type: 'json',
root: 'maListe',
totalProperty: 'Total'
}
}),
Try keeping old json response and store root property (root: 'd.maListe') and modify the totalProperty : 'Total'

jqGrid + ASP.NET WebForm (C#) Search abilities

Ohoy there!
I've been struggling with this problem for days, and I'm really starting to loose my temper about this!
I had managed to get informations parsed back to the grid, which can be sorted, but when I'm trying filtering the results, it gets a little bit messy..
I have been programming C# for about 4-5 months, but my Web Forms, Javascript and JQuery (including JSON) is only about 14 days or so, so maybe it's something very basics I do wrong - please be!!
First, I'm wondering if this is the correct JSON-syntax?
{"grid":{"_search":true,"nd":1291150141196,"rows":20,"page":1,"sidx":"Name","sord":"asc","filters":"{\"groupOp\":\"AND\",\"rules\":[{\"field\":\"Phone\",\"op\":\"eq\",\"data\":\"2343444\"}]}"}}
Those backslashes seems incorrect to me, and I've tried filtering them at server side, but no luck - again, only 14 days of experience.
Error message:
"System.InvalidOperationException"
"Cannot convert object of type 'System.String' to type 'Filter'"
" at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeInternal(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)\r\n at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeMain(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)\r\n at System.Web.Script.Serialization.ObjectConverter.AssignToPropertyOrField(Object propertyValue, Object o, String memberName, JavaScriptSerializer serializer, Boolean throwOnError)\r\n at System.Web.Script.Serialization.ObjectConverter.ConvertDictionaryToObject(IDictionary`2 dictionary, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)\r\n at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeInternal(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)\r\n at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeMain(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)\r\n at System.Web.Script.Services.WebServiceMethodData.StrongTypeParameters(IDictionary`2 rawParams)\r\n at System.Web.Script.Services.WebServiceMethodData.CallMethodFromRawParams(Object target, IDictionary`2 parameters)\r\n at System.Web.Script.Services.RestHandler.InvokeMethod(HttpContext context, WebServiceMethodData methodData, IDictionary`2 rawParams)\r\n at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)"
My WebMethod:
[WebMethod]
[ScriptMethod]
public string GetAll(GridSettings grid) {
var query = from p in dc.Customers select p;
//if (grid._search)
// if (grid.filters.groupOp == "AND")
// {
// foreach (var rule in grid.filters.Rules)
// query = query.Where<Customers>(rule.field, rule.data, rule.oper);
// }
// else if (grid.filters.groupOp == "OR")
// {
// var temp = (new List<Customers>()).AsQueryable();
// foreach (var rule in grid.filters.Rules)
// {
// var t = query.Where<Customers>(rule.field, rule.data, rule.oper);
// temp = temp.Concat<Customers>(t);
// }
// query = temp.Distinct<Customers>();
// }
query = query.OrderBy<Customers>(grid.sidx, grid.sord);
List<Customer> result = new List<Customer>();
foreach (var x in query)
{
Customer y = new Customer();
y.Phone = x.Phone;
y.Name = x.Name;
y.Address = x.Address;
y.Postal = x.Postal;
y.City = x.City;
y.Date = x.Date.ToString("dd-MM-yy");
result.Add(y);
}
return JsonConvert.SerializeObject(new PagedList(result, result.Count(), 1, 20));
}
}
Even through I don't think it's necessarily, (server side don't filter atm.):
public class Customer
{
public string Phone { get; set; }
public string Name { get; set; }
public string Address { get; set;}
public string Postal { get; set; }
public string City { get; set; }
public string Date { get; set; }
}
public class GridSettings
{
public bool _search { get; set; }
public Filter filters { get; set; }
public long nd { get; set; }
public int rows { get; set; }
public int page { get; set; }
public string sidx { get; set; }
public string sord { get; set; }
}
public class Filter
{
public string groupOp { get; set; }
public Rule[] Rules { get; set; }
public static Filter Create(string json)
{
try
{
return JsonConvert.DeserializeObject<Filter>(json);
}
catch
{
return null;
}
}
}
public class Rule
{
private Dictionary<string, WhereOperation> operations = new Dictionary<string, WhereOperation> {
{ "eq",WhereOperation.Equal },
{ "ne",WhereOperation.NotEqual },
{ "cn",WhereOperation.Contains }
};
public string field { get; set; }
public string op { set; get; }
public WhereOperation oper { get { return operations[op]; } }
public string data { get; set; }
}
public static class LinqExtensions
{
public static IQueryable<T> OrderBy<T>(this IQueryable<T> query, string sortColumn, string direction)
{
ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
MemberExpression memberAccess = null;
string methodName = string.Format("OrderBy{0}", direction.ToLower() == "asc" ? "" : "descending");
foreach (var property in sortColumn.Split('.'))
{
memberAccess = MemberExpression.Property(memberAccess ?? (parameter as Expression), property);
}
LambdaExpression orderByLambda = Expression.Lambda(memberAccess, parameter);
MethodCallExpression result = Expression.Call(
typeof(Queryable),
methodName,
new[] { query.ElementType, memberAccess.Type },
query.Expression,
Expression.Quote(orderByLambda));
return query.Provider.CreateQuery<T>(result);
}
public static IQueryable<T> Where<T>(this IQueryable<T> query, string column, object value, WhereOperation operation)
{
try
{
if (string.IsNullOrEmpty(column))
return query;
ParameterExpression parameter = Expression.Parameter(query.ElementType, "p");
MemberExpression memberAccess = null;
foreach (var property in column.Split('.'))
memberAccess = Expression.Property(memberAccess ?? (parameter as Expression), property);
if (memberAccess == null)
return query.Where(p => true);
Expression conditional = Expression.Call(null, typeof(LinqExtensions).GetMethod("Comparer"), Expression.Convert(memberAccess, typeof(object)), Expression.Convert(Expression.Constant(value), typeof(object)), Expression.Constant(operation));
MethodCallExpression result = Expression.Call(typeof(Queryable), "Where", new[] { query.ElementType }, query.Expression, Expression.Lambda(conditional, parameter));
return query.Provider.CreateQuery<T>(result);
}
catch
{
return query.Where(p => true);
}
}
public static bool Comparer(this object value1, object value2, WhereOperation operation)
{
string strValue1 = value1.ToString().ToLowerInvariant().Trim();
string strValue2 = value2.ToString().ToLowerInvariant().Trim();
double dblValue1 = -1;
double dblValue2 = -1;
bool areNumbers = double.TryParse(strValue1, out dblValue1) && double.TryParse(strValue2, out dblValue2);
switch (operation)
{
case WhereOperation.Equal:
return areNumbers ? dblValue1 == dblValue2 : strValue1 == strValue2;
case WhereOperation.NotEqual:
return areNumbers ? dblValue1 != dblValue2 : strValue1 != strValue2;
case WhereOperation.Contains:
return strValue1.Contains(strValue2);
}
return true;
}
}
public enum WhereOperation
{
Equal, NotEqual, Contains
}
public class StringValueAttribute : System.Attribute
{
private string _value;
public StringValueAttribute(string value)
{
_value = value;
}
public string Value
{
get { return _value; }
}
}
public class PagedList
{
IEnumerable _rows;
int _totalRecords;
int _pageIndex;
int _pageSize;
object _userData;
public PagedList(IEnumerable rows, int totalRecords, int pageIndex, int pageSize, object userData)
{
_rows = rows;
_totalRecords = totalRecords;
_pageIndex = pageIndex;
_pageSize = pageSize;
_userData = userData;
}
public PagedList(IEnumerable rows, int totalRecords, int pageIndex, int pageSize)
: this(rows, totalRecords, pageIndex, pageSize, null)
{
}
public int total { get { return (int)Math.Ceiling((decimal)_totalRecords / (decimal)_pageSize); } }
public int page { get { return _pageIndex; } }
public int records { get { return _totalRecords; } }
public IEnumerable rows { get { return _rows; } }
public object userData { get { return _userData; } }
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
}
Any finally Javascript:
$(function () {
$("#CustomerList").dialog({
autoOpen: false,
show: "explode",
width: 720,
height: 450,
open: function () {
$("#CustomerListTable").jqGrid({
datatype: function (pdata) { getListData(pdata, 'Customers', '#CustomerListTable'); },
colNames: ['Telefon', 'Navn', 'Adresse', 'Post', 'By', 'CVR'],
colModel: [
{ name: 'Phone', width: 70, sortable: true, searchoptions: { sopt: ['eq', 'ne', 'cn']} },
{ name: 'Name', width: 200, sortable: true, searchoptions: { sopt: ['eq', 'ne', 'cn']} },
{ name: 'Address', width: 200, sortable: true, searchoptions: { sopt: ['eq', 'ne', 'cn']} },
{ name: 'Postal', width: 60, sortable: true, searchoptions: { sopt: ['eq', 'ne', 'cn']} },
{ name: 'City', width: 100, sortable: true, searchoptions: { sopt: ['eq', 'ne', 'cn']} },
{ name: 'CVR', width: 70, sortable: true, searchoptions: { sopt: ['eq', 'ne', 'cn']} }
],
caption: "",
height: 360,
loadonce: true,
scroll: 1,
pager: '#CustomerListPager',
gridview: true,
sortname: 'Name',
sortorder: 'asc'
});
$("#CustomerListTable").jqGrid('navGrid', '#CustomerListPager', { del: false, add: false, edit: false }, {}, {}, {}, { multipleSearch: true });
}
});
});
function getListData(pdata, controller, table) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Controls/" + controller + ".asmx/GetAll",
data: "{\"grid\":" + JSON.stringify(pdata) + "}",
dataType: "json",
success: function (data, textStatus) {
if (textStatus == "success") RecievedData(JSON.parse(getMain(data)).rows, table);
},
error: function (data, textStatus) {
alert("Error fetching data");
}
});
}
function RecievedData(data, table) {
var thegrid = $(table);
thegrid.clearGridData();
for (var i = 0; i < data.length; i++) thegrid.addRowData(i + 1, data[i]);
thegrid.removeClass("jqgrid-overlay");
}
function getMain(data) {
if (data.hasOwnProperty("d")) return data.d;
else return data;
}
The solution I have this far, is the result of hours and hours of Goggle, reading and experimenting... I'm going about to going nuts!!
Oh and while I'm here - why on earth does the jqGrid search-button show up X times in the #CustomerListPager, when closing / opening the dialog, and why doesn't it request the datas again? I have to refresh the page everytime - which mainly is the reason why I'm using JQuery - i want to avoid that ;)
Thanks for your time if you have read so far - I'm appreciating this!
Happy december!
Nicky.
I do it like this and it loads the data as well as search can be performed easily.
this is the function which is called to load the jqgrid
function FillGrid(WebMethodString, GridName, PagerName, columnModel, columnNames, header)
{
// debugger;
jQuery(GridName).GridUnload();
jQuery.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: WebMethodString,
data: '{}', //PageMethod Parametros de entrada
datatype: "json",
success: function(msg) {
$('#dvWait').css('display', 'block');
// Do interesting things here.
// debugger;
var mydata = jQuery.parseJSON(msg.d);
//console.log(mydata);
jQuery(GridName).jqGrid({
datatype: "local",
data: mydata,
colNames: columnNames,
colModel: columnModel,
pager: jQuery(PagerName),
rowNum: 25,
mtype: "GET",
pagination: true,
scrollOffset: 0,
rowList: [10, 20, 25],
sortname: "WorkOrderID",
scroll: 1,
sortorder: "desc",
multiselect: false,
viewrecords: true,
caption: header,
autowidth: true,
ignoreCase: true,
height: 580,
jsonReader: {
repeatItem: false,
root: function (obj) { return obj.d.rows; },
page: function (obj) { return obj.d.page; },
total: function (obj) { return obj.d.total; },
records: function (obj) { return obj.d.records; }
},
afterInsertRow: function(rowid, rowdata, rowelem) {
jQuery(GridName).setCell(rowid, 'WorkOrderID', '', '', { title: '', onclick: 'DisappearPopup(event);' });
jQuery(GridName).setCell(rowid, 'Requester', '', '', { title: '', onclick: 'DisappearPopup(event);' });
jQuery(GridName).setCell(rowid, 'AssignedTo', '', '', { title: '', onclick: 'DisappearPopup(event);' });
jQuery(GridName).setCell(rowid, 'SummaryText', '', '', { title: '', onclick: 'DisappearPopup(event);' });
jQuery(GridName).setCell(rowid, 'CreationDate', '', '', { title: '', onclick: 'DisappearPopup(event);' });
},
gridComplete: function() {
$('#dvMaintbl').css('visibility', 'visible');
$('#dvWait').css('display', 'none');
}
})
jQuery(GridName).jqGrid('navGrid', PagerName,
{
edit: false,
add: false,
del: false,
searchtext: 'Search',
refreshtext: 'Reload'
});
}
});
}
Add this code in .aspx page
<script type="text/javascript">
// debugger;
jQuery(document).ready(function() {
FillGrid('Json.asmx/GetAllTroubleTickets', '#grid', '#pager', "put your column model here", "put your column names here", "put header text here");
});
</script>
Following is my web service call:
Public Function GetAllTroubleTickets() As String
Dim strStatus As String = HttpContext.Current.Request.QueryString("status")
Dim page As Integer = 1
If HttpContext.Current.Request.Form("page") IsNot Nothing Then
page = Integer.Parse(HttpContext.Current.Request.Form("page").ToString())
End If
Dim rp As Integer = 1
If HttpContext.Current.Request.Form("rowNum") IsNot Nothing Then
rp = Integer.Parse(HttpContext.Current.Request.Form("rowNum").ToString())
End If
Dim start As Integer = ((Page - 1) * rp)
If (strStatus = Nothing) Then
strStatus = "2"
End If
Dim dsDatos As DataSet = GetAllTroubleTicketsclass("", "WorkOrderID asc", "1", "4000", "", Convert.ToInt16(strStatus))
Dim result As String = Jayrock.Json.Conversion.JsonConvert.ExportToString(dsDatos.Tables(0).Rows)
Return result
End Function