I am new to jqGrid and I have found it difficult to follow the documentation jqGrid Documentation
I cannot figure out how to call a WebMethod when setting up the JQGrid. I have been successful in making an Ajax call to get the data and then setting up the JQGrid with local data. I think its an extra step in the setup process and that I should be able to provide the path to the webmethod using the url property.
The editurl property is the same way. I am never actually receiving the post to the server.
Original Code
Attempted JQGrid Setup
function GetData()
{
$('#list').jqGrid({
type: "POST",
url: "Default.aspx/GetUsersJSON",
datatype: "json",
height: 250,
colName: ['Username', 'Email'],
colModel: [
...
}).jqGrid(
'navGrid',
'#pager',
{
edit: true,
add: true,
del: true
});
}
WebMethod
[WebMethod]
public static string GetUsersJSON()
{
var users = new List();
using(UserAdministrationSandboxDataContext uasd = new UserAdministrationSandboxDataContext())
{
users = uasd.GetUserList();
}
JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Serialize(users);
}
Current Code
I got it working correctly now, but I still have one final question. Why did I have to set the 'repeatitems: false' in order to display the content?
Some of the caveats to get this to work include the different ways to setup the ajax request.
(Ajax: type) is (jqgrid : mtype) (Ajax: contentType) is (jqgrid : ajaxGridOptions: { contentType: })
And finally understanding the documentation from the documentation on how to setup the JSONReader.
Hope this helps others and thanks Oleg for all your help.
JS
function GetUserDataFromServer()
{
$('#list').jqGrid({
url: "Default.aspx/GetUsersJSON",
mtype: 'POST',
ajaxGridOptions: { contentType: "application/json" },
datatype: "json",
serializeGridData: function (postData)
{
return JSON.stringify(postData);
},
jsonReader: {
root: function (obj) { return obj.d; },
page: function (obj) { return 1; },
total: function (obj) { return 1; },
records: function (obj) { return obj.d.length; },
id:'0',
cell:'',
repeatitems: false
},
datatype: "json",
height: 250,
colName: ['Username', 'Email'],
colModel: [
{
name: 'Username',
index: 'Username',
width: 100,
editable: true
},
{
name: 'Email',
index: 'Email',
width: 220,
editable: true
},
{
name: 'IsLockedOut',
index: 'IsLockedOut',
width: 100,
editable: true,
edittype: 'checkbox'
}
],
caption: "Users"
})
}
Web Method
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static List GetUsersJSON()
{
using (UserAdministrationSandboxDataContext uasd = new UserAdministrationSandboxDataContext())
{
return uasd.GetUserList();
}
}
One JSON Object from the List
{"__type":"UserAdministrationSandbox.UserData","PKID":"00000000-0000-0000-0000-000000000001","Username":"TestUser","ApplicationName":"Test","Email":"[email protected]","Comment":"TestUser","Password":"D41D8CD98F00B204E9800998ECF8427E","PasswordQuestion":"Is this a blank Password?","PasswordAnswer":null,"IsApproved":true,"LastActivityDate":"\/Date(1298869200000)\/","LastLoginDate":"\/Date(1298869200000)\/","LastPasswordChangedDate":"\/Date(1298869200000)\/","CreationDate":"\/Date(1298869200000)\/","IsOnLine":false,"IsLockedOut":false,"LastLockedOutDate":"\/Date(1298869200000)\/","FailedPasswordAttemptCount":0,"FailedPasswordAttemptWindowStart":null,"FailedPasswordAnswerAttemptCount":null,"FailedPasswordAnswerAttemptWindowStart":null}
First of all I hope the code examples from the answer could help you (see also this answer). The main idea, that you should use following additional jqGrid parameters
ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
serializeGridData: function (postData) {
return JSON.stringify(postData);
},
jsonReader: { root: "d.rows", page: "d.page", total: "d.total",
records: "d.records" };
If the server not set rows
, page
, total
and records
parameter in the response and just return the list of data like in your case you can use the following jsonReader
jsonReader: {
root: function (obj) { return obj.d; },
page: function (obj) { return 1; },
total: function (obj) { return 1; },
records: function (obj) { return obj.d.length; }
}
(see here and here). In the case if you don't want implement server side data paging, sorting and filtering I recommend you to use loadonce:true
.
Moreover your code have some problems. The first one is that you call JavaScriptSerializer.Serialize
manually in your web method. If you use dataType: "json"
the JSON response will be converted to object by $.ajax
. It is so in your case also. Because of that the msg
parameter of the success
handler has d
property. But msg.d
is not the object, but one more JSON string which you convert to object with eval(msg.d)
. The reason is that the results of your method will be converted to JSON one more time.
To fix the problem you should change the web method GetUsersJSON
to the following:
[WebMethod]
[ScriptMethod (ResponseFormat = ResponseFormat.Json)]
public static List<User> GetUsersJSON()
{
using(UserAdministrationSandboxDataContext uasd =
new UserAdministrationSandboxDataContext())
{
return uasd.GetUserList();
}
}
then you can place data: eval(msg.d)
in your previous example to data: msg.d
.
Typically one use additional [ScriptMethod (ResponseFormat = ResponseFormat.Json)]
or [ScriptMethod (UseHttpGet = true, ResponseFormat = ResponseFormat.Json)]
attribute for the web method, but in many cases (it seems also in your case) it is not needed.
After the usage of ajaxGridOptions
, serializeGridData
and jsonReader
jqGrid will able to read the page of data, but the data should be in JSON format and not twice encoded JSON format.
UPDATED: You ask me to comment why you need to use repeatitems:false
setting in the jsonReader
to be able to read your data. It is important question for understanding how jsonReader
work, but the answer will take a little place.
In general there are two main styles how the JSON data can be formatted for jqGrid. It should be array of data for grid rows. Every item of the array represent the row in grid and the row should be in one from the two main form
1) as an object with named properties like
{"Username":"TestUser","Email":"[email protected]","Comment":"..","IsApproved":true}
or 2) an array of strings like
["TestUser","[email protected]","true"]
or
["TestUser","[email protected]","1"]
jqGrid map both "true" and "1" values to the boolean value "true" in case of edittype:'checkbox'
setting. How you can understand if the grid has many checkbox-columns the usage of "1"/"0" format can reduce the size of transfered data.
The repeatitems:false
option means that jqGrid should scan JSON data for the first (object style) representation of data. The repeatitems:true
means the second (array style) representation.
By the way if you use the object style (repeatitems:false
) the cell
setting of the jsonReader
will be not used and you can remove cell:''
setting which you use.
The id
option of the jsonReader
in numeric form is practical if you have one column in the grid with unique values. The option id:'0'
means that the value of the column "Username" will be used as the row id. If you examine the grid with Firebug of Developer tools of IE or Chrome you will see that the corresponding <tr>
element has attribute id="TestUser"
(used in your data). Because duplicate in ids are not allowed on one HTML page, you can understand that it is very important to define grid with correct unique ids. If jqGrid not find id column in the data it will use ids "1", "2", ... So if you see that your grid has the values you should search for the error in the id
property of the jsonReader
.
The next important thing is the advantages and disadvantages of two ways of the data representation: object style (repeatitems:false
) and array style (repeatitems:true
)
The object style has advantage in two main cases
In all other situations the array style (repeatitems:true
) has advantages compared with the object style. The main from there
So if you want to reduce the size of transfered data and you can make changes on the server side I would recommend you to use array style (repeatitems:true
) of representation of data. In the case the cell:''
property of the jsonReader
can be good used.
I recommend you to look though the part of jqGrid documentation about jsonReader
, xmlReader
and localReader
.