views:

6549

answers:

9

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.

A: 

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?

JTew
A: 

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);
    }
   });
  });
Travis
A: 

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
A: 

the d in the json is an inbuilt defense against a potential exploit

example I found that uses mvc

Full info here

redsquare
+9  A: 

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.

nshaw
Are these hacks still necessary as of jqGrid 3.4?
Mike
+2  A: 

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.

Slace
A: 

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"

Element
Good point. If you are just retrieving data, that works. Unfortunately the editing functionality in jqGrid doesn't allow custom Ajax unless you make the changes in the jqGrid code, at least as far as I can tell.
nshaw
A: 

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?

ari
+1  A: 

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") %>',
darren