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.
8 Answers
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.
1 Comment
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.
Comments
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") %>',
Comments
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);
}
});
});
Comments
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
Comments
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"
1 Comment
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?