Has anyone been able to implement the JQuery grid plugin, jqGrid? I'm trying to implement the JSON paging, and I feel like I'm getting close, but that I am also being swamped by inconsequential details. If anyone could post some sample code, I would greatly appreciate it.
I'm looking at doing a similar thing with FlexGrid for jQuery and WCF emitting JSON but I'm still working on it.
Are there particular issues you are encountering?
I'm just floundering trying to pull everything together. My first concern is simply generating a correct JSON response. My returned class appears to be serialised as a property named 'd' - is this a JQuery thing, or ASP.Net web method convention? I'm afraid that jqGrid will be looking for the data to be top-level, whereas asp.net will put it in a property called 'd':
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static object GetData() {
TestClass tc = new TestClass() { One = "Hello", Two = "World" };
return tc;
}
$("#divResults").click(function() {
$.ajax({
type: "POST",
url: "GridData_bak.aspx/GetData",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(test) {
// Replace the div's content with the page method's return.
$("#divResults").text(test.d.One);
},
error: function(msg) {
$("#divResults").text(msg);
}
});
});
Hi Adam The flexgrid plugin is quite sparse on doumentation however in a small section on the demo page there is a tut on creating a json serialized object, this is a bit misleading because the grid requires a specific format, I have ported the php code for xml option with a little monkey grease you can do the same for the json formatting
heres my xml port
the setup for the grid
$("#tableToFlex").flexigrid({
url: 'WebService.asmx/getData'}
... *other configs* ...);
please consider the following code in the webservice.asmx class
<WebMethod()> _
<ScriptMethod(ResponseFormat:=ResponseFormat.Xml)> _
Public Function getData(ByVal page As Integer, _
ByVal qtype As String, _
ByVal Query As String, _
ByVal rp As Integer, _
ByVal sortname As String, _
ByVal sortorder As String) As System.Xml.XmlDocument
'note these parameters are inputted to determine paging and constrains for the resultant rows
'Sample list to send to the grid
Dim list = New List(Of ApplicationStateInformation)
'Sample row object that holds name , surname , address, idnumber ...
list.Add(New RowObjects( "test1", "test1", "test1", "12345"))
list.Add(New RowObjects( "test2", "test2", "test2", "12345"))
list.Add(New RowObjects( "test3", "test3", "test3", "12345"))
list.Add(New RowObjects( "test4", "test4", "test4", "12345"))
'retun a xml doc, as we are using the xml format on the flexgrid
Dim returnDoc = New System.Xml.XmlDocument()
returnDoc.Load(New IO.StringReader(ToXmlResult(list)))
Return returnDoc
End Function
Private Function ToXmlResult(ByVal list As List(Of RowObjects)) As String
'this is the xml document format the grid understands
Dim result As String = "<?xml version=""1.0"" encoding=""utf-8""?>" & vbCrLf
result += "<rows>" & vbCrLf
result += String.Format("<page>{0}</page>" & vbCrLf, "1")
result += String.Format("<total>{0}</total>" & vbCrLf, "10")
For Each item In list
result += ConvertRowData(item)
Next
result += "</rows>" & vbCrLf
Return result
End Function
Private Function ConvertRowData(ByVal row As RowObjects) As String
Dim result As String = String.Format("<row id='{0}'>" & vbCrLf, row.IdNumber.ToString)
'THESE SHOULD BE HTML ENCODED (the format arg) but I left it out
result += String.Format("<cell><![CDATA[{0}]]></cell>" & vbCrLf, row.Name)
result += String.Format("<cell><![CDATA[{0}]]></cell>" & vbCrLf, row.Surname)
result += String.Format("<cell><![CDATA[{0}]]></cell>" & vbCrLf, row.IdNumber)
result += "</row>" & vbCrLf
Return result
End Function
Found your post while I was trying to do this for my project. I got it working. For anyone who needs it in the future, jqGrid won't work out of the box with JSON and ASP.NET. You need to make a couple of small modifications to grid.base.js. Around line 829, replace the json case section with the following:
case "json":
gdata = JSON.stringify(gdata); //ASP.NET expects JSON as a string
$.ajax({ url: ts.p.url,
type: ts.p.mtype,
dataType: "json",
contentType: "application/json; charset=utf-8", //required by ASP.NET
data: gdata,
complete: function(JSON, st) { if (st == "success") { addJSONData(cleanUp(JSON.responseText), ts.grid.bDiv); if (loadComplete) { loadComplete(); } } },
error: function(xhr, st, err) { if (loadError) { loadError(xhr, st, err); } endReq(); },
beforeSend: function(xhr) { if (loadBeforeSend) { loadBeforeSend(xhr); } } });
if (ts.p.loadonce || ts.p.treeGrid) { ts.p.datatype = "local"; }
break;
Then add the following function:
function cleanUp(responseText) {
var myObject = JSON.parse(responseText); //more secure than eval
return myObject.d; //ASP.NET special
}
You will also need to include the JSON parser and stringifier. Along with working with ASP.NET, this revised code is also more secure because the eval statement is gone.
EDIT: I should have also noted that you might have to make similar edits to grid.celledit.js, grid.formedit.js, grid.inlinedit.js, and grid.subgrid.js.
I've just jTemplates for doing client-side paging with jQuery and ASP.NET. I did a blog post on it which you can find here: http://www.aaron-powell.com/blog.aspx?id=1209
It looks at how to create a templated data location, return the data from ASP.NET and then implement a paging solution.
I think you can make jqgrid work with json & asp.net without modifying grid.base.js and other jqgrid files, you have to use the datatype property to define your own custom ajax call and define a json reader, jqgrid will then use your custom ajax call and reader every time the grid reloads.
The process is similar for xml you just define an xmlreader instead of a jsonreader.
All the properties of the jsonreader are defined in the online documentation
For examples of custom datatype see "Function as datatype" in the live demo page under "New in 3.3"
My Implement:
data: "{'page':'" + gdata.page + "','rows':'" + gdata.rows + "','sidx':'" + gdata.sidx + "','sord':'" + gdata.sord + "','nd':'" + gdata.nd + "','_search':'" + gdata._search + "','searchField':'" + ts.p.searchdata.searchField + "','searchString':'" + ts.p.searchdata.searchString + "','searchOper':'" + ts.p.searchdata.searchOper + "'}",
success: function(JSON, st) { if (st == "success") { addJSONData(JSON.d, ts.grid.bDiv); if (loadComplete) { loadComplete(); } }
Insted using complete ajax event use success event. this way is prevent the double json seralize.
Just one thing that i didnt realize with cell editing: Assume that I want edit multiple cells with same data type (int). I have only one web method! and I cant oveload with a same data type with diffrent name! Is anyone solve this kind of probleme?
You can use the ASP.Net MVC JsonResult to populate the grid.
Person Class
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public DateTime Birthday { get; set; }
public static IEnumerable<Person> GetABunchOfPeople()
{
// Get a bunch of People.
}
}
In your controller you would have:
public JsonResult GetABunchOfPeopleAsJson()
{
var rows = (Person.GetABunchOfPeople()
.Select(c => new
{
id = c.ID,
cell = new[]
{
c.ID.ToString(),
c.Name,
c.Birthday.ToShortDateString()
}
})).ToArray();
return new JsonResult
{
Data = new
{
page = 1,
records = rows.Length,
rows,
total = 1
}
};
}
And the jqGrid configuration for the url would be:
url: '<%= ResolveUrl("~/Person/GetAllPeople") %>',