4

I'm sure this is something simple that I'm missing, but I just can't seem to find it. I have a simple jqGrid specified here:

$('#mainGrid').jqGrid({
    datatype: 'local',
    colNames: ['id', 'name'],
    colModel: [
        { name: 'id', index: 'id', width: 100 },
        { name: 'name', index: 'name', width: 300 }
    ],
    rowNum: 9999,
    sortname: 'name',
    viewrecords: true,
    sortorder: 'asc',
    data: [{"id":"924c18a4-cad6-4b6a-97ef-f9ca61614530","name":"Pathway 1"},{"id":"54897f40-49ab-4abd-acac-6047006c7cc7","name":"Pathway 2"},{"id":"61542c48-102f-4d8e-ba9f-c24c64a20d28","name":"Pathway 3"},{"id":"c4ca9575-7353-4c18-b38a-33b383fcd8b2","name":"Pathway 4"}]
});

This loads correctly. Simple proof of concept. Now I try to replace the local data with a call to a server resource:

$('#mainGrid').jqGrid({
    url: 'AJAXHandler.aspx',
    datatype: 'json',
    colNames: ['id', 'name'],
    colModel: [
        { name: 'id', index: 'id', width: 100 },
        { name: 'name', index: 'name', width: 300 }
    ],
    rowNum: 9999,
    sortname: 'name',
    viewrecords: true,
    sortorder: 'asc'
});

The server resource returns the same data. But the grid isn't loading the data. (At least, it's not showing any records.) I've confirmed with FireBug that the resource is indeed being called and is returning the expected data.

At first I thought that the content type in the resource's response should be changed to application/json, but that made no difference. Is there something else wrong with that response that's preventing the grid from loading the data?

Firebug output for the server resource:

Response Headers
  Cache-Control     private
  Content-Length    261
  Content-Type      text/html; charset=utf-8
  Server            Microsoft-IIS/6.0
  MicrosoftSharePointTeamSe...    12.0.0.6219
  X-Powered-By      ASP.NET
  X-AspNet-Version  2.0.50727
  Set-Cookie        WSS_KeepSessionAuthenticated=80; path=/
  Date              Sat, 23 Apr 2011 14:35:43 GMT

Request Headers
  Host              cyber0ne.com
  User-Agent        Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16
  Accept            application/json, text/javascript, */*; q=0.01
  Accept-Language   en-us,en;q=0.5
  Accept-Encoding   gzip,deflate
  Accept-Charset    ISO-8859-1,utf-8;q=0.7,*;q=0.7
  Keep-Alive        115
  Connection        keep-alive
  X-Requested-With  XMLHttpRequest
  Referer           http://cyber0ne.com/dovetail_pages/Member/Pathways.aspx?MemberID=b428e0a7-dd55-de11-8e97-0016cfe25fa3
  Cookie            WSS_KeepSessionAuthenticated=80

Params
  _search   false
  nd        1303569347783
  page      1
  rows      9999
  sidx      name
  sord      asc

Response
  [{"id":"4d4b8249-b5f9-4da6-aba2-bf3af588d560","name":"Pathway 1"},{"id":"230184e6-44cc-4274-97fd-b455440cd9c0","name":"Pathway 2"},{"id":"7f938218-b963-495f-9646-f3cfb1e63ea1","name":"Pathway 3"},{"id":"2b17f23e-5500-4b01-ac1c-df2de90dc511","name":"Pathway 4"}]

Update:

Per @Paul Creasey's answer below, the response content is now:

{"total":4,"page":1,"records":4,"rows":[{"id":"55132687-b0bd-4c89-97cb-122d127429eb","name":"Pathway 1"},{"id":"123ba476-1560-4148-ae96-968bdd10e190","name":"Pathway 2"},{"id":"43f5660b-141c-4ccc-848e-6b41667b399a","name":"Pathway 3"},{"id":"b0d21316-d07d-4b46-8011-89c3cb07a8f6","name":"Pathway 4"}]}

The behavior has changed slightly. The grid now says "Loading" but still doesn't load the data.

David
  • 208,112
  • 36
  • 198
  • 279
  • That link requires authentication, can you post the returned data please. – Paul Creasey Apr 23 '11 at 14:29
  • @Paul Creasey: Ah, an oversight on my part. Editing now to show detailed output... – David Apr 23 '11 at 14:31
  • 1
    You should add 'key:true' in the definition of `id` column. Moreover the value of `total` should be the total number of pages and be 1 in your case. The most important change which you need to do is to include `jsonReader:{cell:''}` if you don't want to change the format of the server response. If your problem will not yet solved I could write you mor einformation in about 2 hours. – Oleg Apr 23 '11 at 16:17
  • @Oleg: As you advise, I've corrected the `total` and added the `key` to the column definition. In this case, changing the server response is fine. I'd rather conform to jqGrid than the other way around where possible. However, the "Loading..." still persists. – David Apr 23 '11 at 16:28

3 Answers3

9

The answer of Paul is absolutely correct. You should just use jsonReader : {repeatitems: false}. I decide to write some more additional information only to clear why jqGrid could not read your original data at the beginning. I want additionally describe how jsonReader parameter can help to read JSON or XML data returned from the server.

First of all you can read almost any input JSON data in jqGrid. You should just define the jsonReader parameter which describe how the data should be read. For example the data in your original format do can be read by jqGrid with respect of the following jsonReader:

jsonReader: {
    repeatitems: false,
    page: function() { return 1; },
    root: function (obj) { return obj; },
    records: function (obj) { return obj.length; }
}

You can see on the demo that the way really works. You can read more about this in my old answer where I suggested to use functions as parameters of jsonReader in situations like youth.

Why is it needed at all to provide the data in so strange form in the server response? Why the jsonReader is needed? The reason is that jqGrid allows the server to implement sorting, paging and optionally filtering/searching. So the request to the server is not like "please get me the list of the users", but more like "please sort the users by the last name and get me the 5-th page of the data where the page consists of 10 rows". The page size (10 in the case) will be get from the combobox of the jwGrid pager. The rowList array parameter defines the list of possible values and the user can choose the page size which he/she prefer.

The returned data should contain not only up to 10 requested rows of the data, but tree additional parameters: "total", "page" and "records" which describes some fields which will be filled in the pager:

enter image description here

The data, which build the grid contain, are array of objects. Every array item hold the information about one grid row. The array item can be either the object with named properties like

{"id":"55132687-b0bd-4c89-97cb-122d127429eb","name":"Pathway 1"}

or the object like

{"id":"55132687-b0bd-4c89-97cb-122d127429eb",
 cell:["55132687-b0bd-4c89-97cb-122d127429eb","Pathway 1"]}

or the arrays like

["55132687-b0bd-4c89-97cb-122d127429eb","Pathway 1"]

To read data in the first format one should use jsonReader:{repeatitems:false}. The second format is default and to read the data one need not define any jsonReader. To read data in the last format we should define jsonReader:{cell:''} and additionally key:true for the id column. The last format in the most compact, but it can be used only if one from the column of jqGrid has unique data which can be interpret as the id. The id is important, because jqGrid build HTML table with <tr> element having exactly the id which one post back. No id duplicates inside one page are permitted corresponds to HTML specifications.

The final remark. If you don't can or don't want to implement paging and sorting on the server side you should return all data in the server response and use loadonce:true parameter of jqGrid. This will follow to changing the datatype parameter of jqGrid to 'local' after the first data load. After that, the sorting and paging of data will be done inside of JavaScript code of jqGrid.

Community
  • 1
  • 1
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • Brilliant! This will definitely help me as I further use jqGrid in this project. And this is _excellent_ content to add to this question for posterity in Stack Overflow. I only wish I could upvote this more than once :) – David Apr 23 '11 at 19:17
  • @David: You are welcome! The information from [the documentation](http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data) is too "dry". So I decide to write a little more. It would be probably needed to describe more the input parameter send to the server, but in the case the text will be even more longer as it be. I am glad if I could help you or other people. – Oleg Apr 23 '11 at 19:25
2

According to the docs here, the expected json format is:

{ 
  "total": "xxx", 
  "page": "yyy", 
  "records": "zzz",
  "rows" : [
    {"id" :"1", "cell" :["cell11", "cell12", "cell13"]},
    {"id" :"2", "cell":["cell21", "cell22", "cell23"]},
      ...
  ]
}

Therefore you web service should be returning this:

{
    "total": "4",
    "page": "1",
    "records": "4",
    "rows" : [
        {
            "id": "4d4b8249-b5f9-4da6-aba2-bf3af588d560",
            "name": "Pathway 1" 
        },
        {
            "id": "230184e6-44cc-4274-97fd-b455440cd9c0",
            "name": "Pathway 2" 
        },
        {
            "id": "7f938218-b963-495f-9646-f3cfb1e63ea1",
            "name": "Pathway 3" 
        },
        {
            "id": "2b17f23e-5500-4b01-ac1c-df2de90dc511",
            "name": "Pathway 4" 
        } 
    ]
}

At the moment you only have the rows array.

You could implement your own function to read the json, but i've never done this, see the "jsonReader as Function" section of the link above.


Edit:

I was wrong initially, either you should set the repeatitems flag to false:

jsonReader : {
   repeatitems: false
},

and use the json above (i think!) or return data like this:

{
    "total": "4",
    "page": "1",
    "records": "4",
    "rows" : [
        {
            "id": "4d4b8249-b5f9-4da6-aba2-bf3af588d560",
            "cells" : ["Pathway 1"]
        },
        {
            "id": "230184e6-44cc-4274-97fd-b455440cd9c0",
            "cells" : ["Pathway 2"]
        },
        {
            "id": "7f938218-b963-495f-9646-f3cfb1e63ea1",
            "cells" : ["Pathway 3"]
        },
        {
            "id": "2b17f23e-5500-4b01-ac1c-df2de90dc511",
            "cells" : ["Pathway 4"] 
        } 
    ]
}

I've always done the latter, but i think the former is probably better!

Paul Creasey
  • 28,321
  • 10
  • 54
  • 90
  • Indeed, I'd forgotten that bit. I've updated the server-side code to wrap the list of items in a parent object which the necessary fields, and I'll update the question to show the new output. The behavior now is that the grid says "Loading" indefinitely. – David Apr 23 '11 at 16:09
  • 1
    & @David: You are right of course Paul the setting `jsonReader : {repeatitems: false}` is correct way. See [the demo](http://www.ok-soft-gmbh.com/jqGrid/David.htm). I was incorrect in my previous comment. – Oleg Apr 23 '11 at 17:12
  • That did it, thanks! I went with the former of your two suggestions, as I'm not entirely sure the _best_ way to construct the server-side objects to produce the latter (using .NET's JavaScriptSerializer on some models). Though I imagine I'll tinker with that as well. – David Apr 23 '11 at 17:17
0

I faced a similar problem in my project in firefox. I am trying to load data into jqgrid on page load. But i just see 'Loading...' and no data in grid.

I solved it in a single step. This may sound silly, but this is just what i did to get it working:

I just commented out the <script> tag in my <head> that points to the js file: jquery.jqGrid.js, as i already have another <script> tag that points to the js file: jquery.jqGrid.min.js

Also you need to ensure that the order of your scripts is correct... first load the jquery and then the jqgrid files.

This resolved my issue of data loading in firefox.

shasi kanth
  • 6,987
  • 24
  • 106
  • 158