Loading JSON data in jqGrid - jqgrid

I'm having troubles when showing my json data in jqGrid.
I've searched a lot in this forum and tried various forms to make it work. I apologize if this was already answered but I really need help with this one.
At the server page I was only using JavaScriptSerializer to send the data and the jsonreader function with the default parameters (this worked ok).
I now need to paginate and have changed my server page code to work with the sidx, sord, page, rows parameters.
The resulting string from the server looks like this:
{"total":"344","page":"1","records":"8577","root":[{"Id":"1","SerialNumber":"132","Name":"ServerName"},...]}
Here is my jQuery code:
$("#list").jqGrid({
datatype: "json",
mtype: 'GET',
url:'https://server/handlerpage.ashx',
colNames:['Id','SerialNumber','Name'],
colModel :[
{name:'Id', index:'Id', jsonmap:"Id", width:20},
{name:'Name', index:'Name', jsonmap:"Name", width:120},
{name:'SerialNumber', index:'SerialNumber', jsonmap:"SerialNumber", width:100}],
jsonreader: {repeatitems:false,id:'Id',root:'root'},
pager: '#pager',
rowNum:25,
rowList:[25,50,75,100],
sortname: 'Id',
viewrecords:true,
gridview: true,
height:"400",
width:"700",
caption: 'Select from existing server',
loadtext:'Loading, please wait'
}).navGrid("#pager", { edit: false, add: false, search: true, del: false });

In order to use json data as a response from a query the response has to be formatted correctly. It is difficult to determine what is the correct response and how to get it from the documents. More problems can occur as a result of your server settings generating a warning as part of the response which will cause the grid not to load.
From the documents this is the default json reader, meaning if you format your response correctly you don't need to add anything / a custom json reader.
jsonReader : {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: true,
cell: "cell",
id: "id",
userdata: "userdata",
subgrid: {
root:"rows",
repeatitems: true,
cell:"cell"
}
First make sure you have the right response format. {"page":1,"total":1,"records":"2","rows":[{"id":"1","cell":["1","mydata1"]},{"id":"2","cell":["2","mydata2"]}]}
No sample is given on the docs page but the above is correct if you only have two columns in your grid. You need to get your server query / parsing of your server query and values passed to the page that runs your sever side scripts to return this format. The example.php page from the documents gives you all the values you need.
This code will give you the proper header, to avoid error warnings and matches up with the response from above. Also note that in the docs they do not add the apostrophes around the indexes for the associative array index names. That will fail.
header('Content-type: application/json');$responce = new stdClass();$responce->page = $page;$responce->total = $total_pages;$responce->records = $count;$i=0;while($row = mysql_fetch_array($result,MYSQL_ASSOC)) {$responce->rows[$i]['id']=$row['ID'];$responce->rows[$i]['cell']=array($row['ID'],$row['entity_name']); $i++; } echo json_encode($responce);
To rehash what is missing in the docs (it is possible that I just missed them and even if, the documents for jQgrid are epic/a masters work):
1. No mention of the need for a header statement for json (it is clear with the XML examples)
2. No sample of what a working returned string should look like
3. Lack of proper formatting of the associative array indexes.
4. No mention of how to avoid a PHP warning being returned as part of the response

Try the following
jsonReader: {
root: 'rows',
page: 'page',
total: 'total',
records: 'records',
repeatitems: true,
cell: 'cell',
id: 'id',
userdata: 'userdata'
}

Please make sure that the server side script is returning proper json string with HEADERS
Further check the demo site and JSON example

Related

jqgrid colmodel editoptions to load json result

I want to load my server data in the DropDown of my jqgrid. My code,
UPDATED CODE:
public ActionResult GetUnit()
{
List<UnitModel> getUnitValues = new List<UnitModel>();
//ToDo db code
Dictionary<int, string> unitValues = new Dictionary<int, string>();
unitValues = getUnitValues.ToDictionary(x => x.UnitID, x => x.UnitDesc);
unitValues.Add(4, "Unit2/3");
unitValues.Add(1, "Unit1");
unitValues.Add(2, "Unit2");
unitValues.Add(3, "Unit3");
return Json(unitValues, JsonRequestBehavior.AllowGet);
}
My jqgrid:
colModel: [...
{
name: 'UnitID', index: 'UnitID', editable: true, edittype: 'select', width: "200",
formatter: 'select', editoptions: { value: unitslist},
editrules: { custom: true, custom_func: dupicateRecordValidation
}
},
...],
beforeProcessing: function () {
$.ajax({
url: '/Home/GetUnit/',
dataType: 'json',
type: 'POST',
contentType: 'application/json; charset=utf-8',
success: function (data) {
$.map(data, function (value, key) {
unitsList += '"' + value + '"' + ':' + '"' + key + '"' + ',';
});
unitsList += '}';
alert(unitsList);
}
});
},
But, this isn't working. The jqgrid DropDown column loaded with empty cell. Am I missing something? Is this the correct way to do? Please suggest if any alternate way to load the dropdown of jqgrid with server data with default value of that row being selected. Thanks.
Note:I'm using Jquery jqgrid v4.4.4 Visual Studio
First of all, it's important to understand when you should use formatter: 'select', which you currently use. It's required if you want to fill the grid with id information in UnitID, but you need to display the text, which correspond the ids. For example, the JSON data, which you get from the server could contain the property language, with the content "de", "en", "fr" and so on, but you want to display in the column "German" instead of "de", "English" instead of "en" and "French" instead of "fr". In the case you should define
formatter: 'select', editoptions: { value: 'de:German;en:English;fr:French' },
editable: true, edittype: 'select'
If you really need to use formatter: 'select', and you need to load the editoptions.value via Ajax from the server, then the editoptions.value have to be set before the main data of the grid returned from url will be processed. In the case, I would recommend you to extend the standard data returned from url with the data required for the editoptions.value. One can use beforeProcessing callback (which is supported even in the retro version 4.4.4, which you use) and to set editoptions.value dynamically with respect of setColProp method. See the answer for more details and the code example.
If you don't need to use formatter: 'select' (if ids and the values, used in select, are the same), then you can change the format of data returned from GetUnit action to the serialized array:
["Unit1", "Unit2", "Unit2/3"]
and to use dataUrl with buildSelect properties of editoptions instead of value. The value of dataUrl should be URL of GetUnit action, which return array of strings with all utits. The callback buildSelect should convert the JSON array to HTML fragment, which represent <select> with all the options. See the old answer, for more implementation details and code examples.
Finally, you should fix width: "200px" to width: 200. The value of width property should be the number or the string which could be converted to the number. The usage of px or and other suffix is wrong. The next recommend fix would be removing index: 'UnitID' and all other index properties from colModel, if the value of index property is the same as the value of name property.

free jqgrid custom formatter lost after sorting or filtering

I am using free jqgrid 4.13.0
I wrote a custom formatter, but unfortunately my cell contents of that column are always lost after sorting the table or filtering. I am probably doing something wrong in the formatter function, but haven't really understood what is missing. Anyone can spot my mistake? Why is it working fine with the built in ones, but not with mine. I got inspired by this one: http://www.ok-soft-gmbh.com/jqGrid/CascadingFormater.htm
I can see how the example is calling $.fn.fmatter.call and maybe I need to do this too. Is this the key? Unfortunately I can't find any documentation on how to do this if I write the function myself.
This is my setup:
var formatEnduser = function (cellValue, options, rowObject, action){
return rowObject.so_enduser_id == undefined ? '' : ''+rowObject.so_enduser_name+'';
}
$("#jqGrid").jqGrid({
datatype: "jsonstring",
datastr: jsonData,
jsonReader: {
root: 'rows',
id: 'crmentity_id',
repeatitems: false,
page: function(obj) { return 1; },
total: function(obj) { return 1; },
records: function(obj) { return obj.rows.length; },
},
autowidth: true,
height: 600,
shrinkToFit: true,
rownumbers: true,
rowNum: 5,
pager: false,
loadonce: true,
viewrecords: true,
colModel: [
{
name: 'crmentity_id',
key: true,
hidden: true
},
{
label: 'Enduser',
name: 'so_enduser_name',
searchoptions: {
sopt : ['cn']
},
formatter: formatEnduser
},
]
});
$('#jqGrid').jqGrid('filterToolbar');
The object jsonData looks like this:
Object { rows=[623], so_total_total=4321, in_total_total=1234 }
In the property rows can be found this:
[Object { crmentity_id="60199", so_enduser_id="6808", so_enduser_name="enduser123", mehr...}, Object { crmentity_id="60136", so_enduser_id="6362", so_enduser_name="userend321", mehr...}, 620 mehr...]
Thanks a lot for any help!
EDIT: I added a jsfiddle to demonstrate the problem, search for end in the filter and see how the data disappears. Sorting does the same. http://jsfiddle.net/tztj9yn7/2/
The main problem is your code is the following. You use datatype: "jsonstring" and the custom formatter uses the property so_enduser_id of the input data, but the property is not a column of the grid. The datatype "jsonstring" will be processed in the same way like the datatype "json" (or "jsonp" or "xml"). It will be read by jqGrid and saved locally only the columns from colModel and jsonReader.id additionally. Thus the property so_enduser_id of the input data will be available in rowObject only during initial reading of the grid. All what I wrote till now is the same for old jqGrid and for free jqGrid.
In case of usage old jqGrid there are two alternative ways to fix the problem:
add hidden column with name: "so_enduser_id"
replace datatype: "jsonstring", datastr: jsonData to datatype: "local", data: jsonData.rows and replace jsonReader to localReader: { id: 'crmentity_id' }. The input data will be saved with all properties (like it be in the input) in case of usage datatype: "local" and the problem will be fixed.
If you would need to load the data directly from the URL then the second way (datatype: "local") will be not possible and the only way will be the usage of hidden columns for all properties which you need later.
Free jqGrid provides you another very simple way: the usage of additionalProperties option. The idea of additionalProperties is very simple. One need sometimes to save some additional properties from every item of input data to use there locally later (because of usage of loadonce: true). Saving the data in DOM is much more expensive as saving the data in the JavaScript structures. One can just use the option like additionalProperties: ["crmentity_id", "so_enduser_id"] to inform free jqGrid to read some other properties and to save there locally. As the result your code will be fixed immediately: see http://jsfiddle.net/tztj9yn7/3/
One more important recommendation about the usage of custom formatters in free jqGrid. There are exist some important problem with the rowObject parameter. It's just the input item exactly like it be in the source. Thus if you would use datatype: "xml" for example then the rowObject parameter would be XML node. In the same way, if you would use repeatitems: true format (["60199", "6808", "enduser123"] instead of {crmentity_id:"60199", so_enduser_id:"6808", so_enduser_name:"enduser123"}) then you will have to use rowObject[1] instead of rowObject.so_enduser_id to access the property so_enduser_id from initial input data. On the next sorting or filtering you will have another format of rowObject (rowObject.so_enduser_id) because of the input data will be the data from the local data parameter. Free jqGrid still use the same format of rowObject parameter to provides the best compatibility with the old versions of jqGrid, but it set additionally rowData property of the options parameter. The options.rowData have always deterministic named format of data and one can use always options.rowData.so_enduser_id independent from the format of the input data and the datatype used. Thus options.rowData is preferred way to access input data. One should't use the third parameter at all. The resulting code of the formatter will be
var formatEnduser = function (cellValue, options) {
var item = options.rowData;
return item.so_enduser_id == undefined ?
'' :
'<a href="index.php?module=Accounts&view=Detail&record=' +
item.so_enduser_id + '">' + item.so_enduser_name + '</a>';
};
See http://jsfiddle.net/tztj9yn7/4/

jqGrid : searchrules in single Field searching

I'm trying to validate the search field for integer data alone but unfortunately am unable to do so. I have tried all possible solutions like searchrules:{required:true,integer=true} etc..
But none of them proves fruitful.
I basically launch the search dialog with the field and without inputting any data, am hitting on the 'Find' button. As per the above options, i believe a validation message should be shown to the user asking him to enter a value in the field before hitting find.
[UPDATED] - Code Snippet
var grid = $("#list");
grid.jqGrid({
url:'/index.jsp',
datatype: 'json',
mtype: 'POST',
colNames:['Name','Age', 'Address'],
colModel :[
{name:'name', index:'name', width:55,search:true },
{name:'age', index:'age',
width:90,editable:true,search:true, stype:'text',
searchrules:{required:true,integer:true}},
{name:'address', index:'address', width:80,
align:'right', editable: true,search:false }
],
pager: '#pager',
jsonReader : {
root:"address",
page: "page",
total: "total",
records: "records",
repeatitems: false
},
rowNum:10,
rowList:[10,20,30],
sortname: 'name',
sortorder: 'desc',
viewrecords: true,
gridview: true,
autowidth: true,
toppager: true,
loadtext: "Loading records.....",
caption: 'Test Grid',
gridComplete: function(){
}
});
**grid**.jqGrid('navGrid','#pager',
{view:true,edit:true,add:true,del:true,refresh:true,
refreshtext:'Refresh',addtext:'Add',
edittext:'Edit',cloneToTop:true,
edittitle: "Edit selected row"},
{},{},{},
{caption: "Search The Grid",Find: "Find Value",Reset: "Reset"},
{});
[Updated] : Am not able to make the searchrules properly work for the single/advanced searching modes.
[Updated] : Even the 'Validation in Search' in
jqGrid Demo is not working for searchrules.
The reason of described problem is a bug in jqGrid. The line
ret = $.jgrid.checkValues(val, -1, null, colModelItem.searchrules, colModelItem.label);
initialize the third parameter of $.jgrid.checkValues to null, but the last version of checkValues implementation started (see the line) with
var cm = g.p.colModel;
but g is initialized to null. The last modification which generates the error was based on my suggestion, but I don't wrote the part of the code.
One can solve the problem in different way. I would suggest to modify the line where $.jgrid.checkValues will be called with null parameter to the following
ret = $.jgrid.checkValues(val, -1, {p: {colModel: p.columns}}, colModelItem.searchrules, colModelItem.label);
Additionally, to be sure, I would suggest to modify one more line
if(!nm) { nm = g.p.colNames[valref]; }
to
if(!nm) { nm = g.p.colNames != null ? g.p.colNames[valref] : cm.label; }
The fixed version of jquery.jqGrid.src.js one can get here. I will post my bug report with the same suggestions later ti trirand.

customize: POST output in jqGrid without changing source file?

I'm trying to turn jqGrid within MODx, as do other data exchange using "$. ajax", move the call from a URL to a resource protected by a password and from there call a snippet of code in PHP, so the security framework, the ajax call is guaranteed
This is one example of a chunk $.ajax:
$.ajax ({
url :'[[~94]]',
type: 'post',
async: false,
success: function(rsp) {
$.Cookie("xxxxxx-tipodirlist", rsp);
}
});
*[[~94]] is a protected resource is within a snippet call [[!SnpBridgedata_blabla]]
the system works perfectly well throughout the web application, receiving and sending data safely and securely.
Now a customer asked me for a completed application wanted web results in a good grid and after seeing a bit of code I decided to use jqGrid for my project.
integration was quick and I am very happy to have changed "DataTable" with "jqGrid," but when I finished the test, change the absolute path to xxxxxx.php with the call to snippet
this is the code for jqGrid:
chargeSedi function (idx)
{
// Test with file. Php !work fine!
// Var esURL = 'http://xxxxx.com/xxxxxxx.php?IDX =' + idx;
// Test with MODx resource !not work!
esURL var = '[[~ 97]] & IDX =' + idx;
csURL var = '[[~ 96]] & IDX =' + idx;
tipodirlist = $ var. cookie ("xxxxxxxx-tipodirlist");
tiposedelist = $ var. cookie ("xxxxxxx-tiposedelist");
$("#sediTable").ready(function() {
$("#sediTable").jqGrid({
url:csURL,
datatype: "json",
height: 250,
autowidth:true,
colNames:[ 'ID','CODICE', 'NOME','TDIR', 'DIR','COMUNE', 'PROVINCIA','CAP', 'TSEDE','NOTA'],
colModel:[
{name:'ID',index:'ID', width:25, editable: false},
{name:'CODICE',index:'CODICE', width:60, editable: true},
{name:'NOME',index:'NOME', width:60, editable: true},
{name:'TDIR',index:'TDIR', width:60, editable: true,edittype:"select",editoptions:{value:tipodirlist}},
{name:'DIR',index:'DIR', width:200, sortable:false,editable: true},
{name:'COMUNE',index:'COMUNE', width:170, sortable:false,editable: true},
{name:'PROVINCIA',index:'PROVINCIA', width:170, sortable:false,editable: true},
{name:'CAP',index:'CAP', width:40, sortable:false,editable: true},
{name:'TSEDE',index:'TSEDE', width:90, editable: true,edittype:"select",editoptions:{value:tiposedelist}},
{name:'NOTA',index:'NOTA', width:170, sortable:false,editable: true,edittype:"textarea", editoptions:{rows:"2",cols:"10"}} ],
sortname: 'ID',
viewrecords: true,
sortorder: "desc",
loadonce: true,
editurl: esURL ,
caption: "Sedi" });
});
]
and for my surprise the MODx deny Access to jqGrid ajax calls, as if you were out of session, but after hours testing and watching the traffic with wireshark I realized that jqGrid sends a POST variable called "id" and call MODx a GET variable "id". this in other environments is possible without problem, but it is not possible MODx and there's the problem.
my question is how I can change the name of the POST variable "id" jqGrid, without changing the source of jqGrid?
at the same time wanted to ask, you can customize the import of a select the value and not the index
example of trame POST:
{Name: 'TDIR', index: 'TDIR', width: 60, editable: true, EditType: "select" editoptions: {value: tipodirlist}}
tipodirlist = 1:via;2:piazza;3:ect
TDIR=2
CODICE=1&NOME=principale&TDIR=2&DIR=Roma&COMUNE=Torino&PROVINCIA=Torino&CAP=10000&TSEDE=2&NOTA=NO=edit&id=0
for this:
TDIR=piazza
CODICE=1&NOME=principale&TDIR=piazza&DIR=Roma&COMUNE=Torino&PROVINCIA=Torino&CAP=10000&TSEDE=2&NOTA=NO=edit&id=0
without having to filter the results on the server.
I hope I've explained well and clear. as I asked myself, the team "StackOverflow" before asking this question
Thank you so much
Regards
niro.
PS.I hope that GOD "Oleg" help me:)
I don't know and don't use MODx. Nevertheless I hope that your problem is: how to rename the name of the id parameter to have no conflict with the id parameter used by MODx.
If I understand your question correct you should just add additional prmNames parameter which set the new name of id parameter used in editing operations:
prmNames: {id: 'myId'}
The example will rename the default id parameter name ({id: "id"}) to myId which you should you in your server part.

JQGrid 'undefined' error

I am getting a JavaScript error when trying to use the JQGrid:
"Message: 'undefined' is null or not an object"
When I debug on my server, I see that my JSON output looks like this: (does it matter that the "id" value is not inside double quotes?)
{
"page":"1",
"total":"20",
"records":"5",
"rows":[
{"id":1,"name":"Sam","phone":"732-333-2222"},
{"id":2,"name":"Dan","phone":"000-222-1111"},
{"id":6,"name":"George","phone":"333333"},
{"id":4,"name":"Jerry","phone":"332-333-4444"},
{"id":7,"name":"John","phone":"666666"},
{"id":8,"name":"Tom","phone":"3333"}]
}
.. and my page looks like this:
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery("#list").jqGrid({
url:'/myUrlPage',
datatype: 'json',
mtype: 'GET',
colNames:['Id', 'Name', 'Phone'],
colModel :[
{name:'id', index:'id', width:55},
{name:'name', index:'name', width:90},
{name:'phone', index:'phone', width:150, sortable:false} ],
pager: jQuery('#pager'),
rowNum:10, rowList:[10,20,30],
sortname: 'id',
sortorder: "desc",
viewrecords: true,
imgpath: 'themes/basic/images',
caption: 'My first grid' }); });
</script>
You main problem will be solved if you include
jsonReader: { repeatitems: false }
parameter in your jqGrid. See details in the jqGrid documentation.
Moreover I modified a little your demo. You can see it here. I recommend you remove deprecated imgpath parameter. Instead of that I recommend you to use height: 'auto' which gives you good results in the most cases. Instead of jQuery('#pager') is better to use just '#pager'. You should additionally increase the value of the width for some columns in case of the usage of pager and viewrecords: true. I included in my demo the jQuery("#pager_left").hide(); statement which hide some block of the pager which you not use now. If you will start to use navigator buttons you should remove the line.
One more remarks about the JSON data which you use. The values of id, page, total and records properties can be either strings or integers, so "id":1 will gives you the same results as "id":"1".
It's important to understand how you should fill page, total and records. You current values are page=1, total=20, records=5 and you data contain 6 rows. All the data has no sense. The jqgrid asked the server with respect of additional parameters which it appended to the URL to gives one page of the data with 10 rows per page (rowNum:10). Your answer from the server means that your data contain 5 items (records=5) totally. If you order the data (the 5 items) in pages (10 items per page) you will have 20 pages (total=20) and the first one from there (page=1) you are filled with the data (6 items). The strange values of page, total and records from your JSON data follows to strange values in the pager on the demo:
I would recommend you to read the answer where I tried to describe why jqGrid need so strange format of JSON data.

Resources