jqGrid: reload data from json-string - javascript

I know, that there is several similar questions are exists on SO, but despite it I creating this question because:
- I still don't get it :)
- I want to create a topic that possibly will cover a problem more complete.
I reconstructed my production setup in simplified way, it available by link below.
In short - I have simple jqGrid, that uses jsonstring as dataType, and datastr with JSON data. And then by firing this:
$("#grid").setGridParam({'datastr': myNewData}).trigger('reloadGrid');
Im trying to reload data in grid, but it just doesnt work.
What am I missing?
ps
Also it is matter for me, that grid has summary row which defined with userdata.
DOWNLOAD SETUP

It's very seldom that you really need to use datatype which values other as "local", "json", "jsonp" or "xml". Most usage of other datatype can be easy replace to the tree main datatypes. If you use "jsonstring", "xmlstring" or "clientSide" then the datatype will be changed to "local" after loading of data (see the line of source code for example). So if you really need to use datatype: "jsonstring" you can fix reloading by usage
$("#grid").setGridParam({
datastr: myNewData,
datatype: "jsonstring" // !!! reset datatype
}).trigger("reloadGrid");
Additionally I could see that you used pager: false option of jqGrid. It's wrong option. If you don't need to use local paging of data I recommend you
don't include and pager option. Default value pager: "" is already OK.
include rowNum parameter with some large enough value like rowNum: 10000. Default value of rowNum is 20. So if you don't want to display only the first 20 rows of the input data you should increase the value of rowNum.
The last recommendation: you should include sorttype: "integer" (see the documentation) to columns which holds integer values. It will fix sorting of data if the user clicks on the column header. You should consider to use column templates too (see the old answer).

Related

jqgrid treegrid how to reload data?

I know how to reload normal jqgrid table. I used the same method to reload treegrid, but it doesn't work.
The usual method to reload jqgrid:
$jqGrid.jqGrid('setGridParam',{
url:path+"/admin/demo/getLogsGridJson.do",
postData:{'aaa':111,'bbb':222}, //
page:1
}).trigger("reloadGrid");
This way I can again request and refresh data. But with treegrid it doesn't work.
How to reload treegrid to use new postData or new url?
To reload the jqGrid TreeGrid with new post data you will need to set treedattype to json like this
$jqGrid.jqGrid('setGridParam',{
url:path+"/admin/demo/getLogsGridJson.do",
postData:{'aaa':111,'bbb':222}, //
page:1,
treedatatype : 'json'
}).trigger("reloadGrid");
More about why is this you can read in Guriddo jqGrid Documenatation here
Kind Regards
Try to reset treeANode parameter of TreeGrid to -1. You can replace unneeded setting of page:1 to treeANode:-1. You can consider to add data: [], _index: {} to the options of setGridParam to improve the performance if you loaded previously large set of data.

Refresh button to call javascript function

In a page, I have a form and a JQGrid. The form is used to enter specific filters. So the Javascript for that page contains a function which reloads the data in order to populate the JQGrid. The JQGrid has loadonce: true, so the refresh button doesn't do anything. I would need to make it call my existing function. Is it possible ?
If I understand you correctly then your problem exist because loadonce: true option changes the original datatype ("json" or "xml") to "local". It allows to use local paging, sorting and filtering of data. During the paging, filtering and sorting the grid will be reloaded, so local reloading do have sense.
If you need to reload the grid from the server you should first restore the original value of datatype and then do reloading.
So if you can use beforeRefresh callback of navGrid to reset datatype:
$("#grid").jqGrid("navGrid", "#pager", {
beforeRefresh: function () {
$(this).jqGrid("setGridParam", {datatype: "json"});
}
});
If you use free jqGrid then you can use new fromServer: true option of reloadGrid and you can use new style of options and new reloadGridOptions option of navGrid. The code will be like
$("#grid").jqGrid({
// standard jqGrid options
navOptions: {
// default options of navGrid
reloadGridOptions: {fromServer: true}
}
}).jqGrid("navGrid");
It will work with datatype:"json" or datatype:"xml".
A simple enough fix:
loadonce: false
really, setting this to true will serve no other purpose that you have specified.

Sending lists of variables to python via AJAX through JQuery

In my project I have javascript iterating through a set of radio buttons. First it checks to see if the selected button in the nameset has been changed, then if it has been, it records the value of the newly selected button for that row, appending it to a variable dataString, before moving on to the next buttonset. This is all well and good, it collects all the data perfectly. I run into issues when I try to send that data through AJAX, however.
For each row that is changed, I append a rowName variable and a deviceName variable do dataString. Ideally I want to send these such that when I get the data to Python, I end up with a rowName list and a deviceName list, as happens when you send multiple variables of the same name.
My AJAX call is as follows:
var call= $.ajax({
type: "POST",
url: "http://localhost/cgi-bin/savestate.py",
data: dataString
}).done(function() {
document.getElementById("upper").innerHTML+=(call.responseText);
});
As I said, the data I need to send gets collected well enough. Right now, dataString is formatted so that it looks like this:
"{rowName: 'firstRowName', deviceName: 'firstDeviceName', rowName: 'secondRowName', deviceName: 'secondDeviceName'}"
I have also tried changing the AJAX call so that the data: call looks like:
data: {dataString}
And formatted dataString to look like:
"rowName: 'firstRowName', deviceName: 'firstDeviceName', rowName: 'secondRowName', deviceName: 'secondDeviceName'"
Either way I try to send it, the data does not get to the python script. When I return the data from Python, it comes out as
FieldStorage(None, None, [])
Now since the format of the data: attribute in the AJAX call is {keyname: value, etc}, is it possible to send the data in a premade list in that format, or do I have to change the way I've formatted dataString and send it some other way?
I ended up achieving the desired effect two ways.
First Method: Thinking back to how I performed AJAX requests prior to implementing JQuery, I formatted dataString to
rowName=firstRowName&deviceName=firstDeviceName&rowName=secondRowName&deviceName=secondDeviceName
and so on. Then I simply appended that to my url in the AJAX call, so that it looked like:
url:"http://localhost/cgi-bin/saveState.py"+dataString
Second Method: The other way that I got it to work was to format the dataString the same way as in the First Method, but then simply use that as my data attribute.
data: dataString
I found it strange that this worked, since it doesn't at all follow the usual format for the data: call. But alas, it did indeed work.
In your initial attempt, you are sending POST data to your Ajax method in JSON format. However, FieldStorage is expecting it in form format (application/x-www-form-urlencoded). The two methods you mention in your answer give it to the Ajax method in form format.
Besides your solutions, another approach is to use a JSON parsing library instead of FieldStorage. Exactly how you do this depends on the framework you are using - is it Django, Pyramid, etc?

jqGrid: Sorting local data clears grid

I've found similar but not identical questions on here; none of their posted answers solve this.
I have local data loaded using addJSONData. When you click a column header to sort, the grid is wiped. There are no errors in the web console/firebug. Data added by later calls to addJSONData is sorted by the selected column, at least.
My config:
jQuery('#attributes').jqGrid({
sortable:true,
datatype:"local",
colNames: cols,
colModel: colmods,
cmTemplate: {width:155, align:"left"},
multiselct: false,
shrinkToFit:false,
caption: "Node Attributes",
scroll: true,
footerrow: true,
userDataOnFooter: true,
rowNum: -1
});
My only idea is to save the data onSortCol and reload it in loadComplete. I don't much like that though. I've tried various combinations of rowNum: 9007199254740992, loadonce: true and others.
I've tried jqGrid versions 4.2.0 and 4.4.0 (in which rowNum: -1 is supported again).
Edit: The line that clears the data is the emptyRows bit in the sortData function:
if(ts.p.scroll) {
var sscroll = ts.grid.bDiv.scrollLeft;
emptyRows.call(ts, true, false);
ts.grid.hDiv.scrollLeft = sscroll;
}
Seems like the data should be saved before this happens, but I'm not familiar with this code to know where the data actually lives.
I'm newcomer to jqGRid (I only started to use it 3 days ago...) but, if you are using local, don't you also have to specify loadonce:true for sorting and paging to work?
I had a similar issue. I stumbled onto a fix though. After setting loadonce: true, if you hit the refresh button in the pager and then try to sort, it works fine.
So I force a click on the refresh button by doing something like: $(".ui-icon-refresh").trigger('click');
I ran this on the onClose event because that suited my requirements. You can check out my entire explanation on this issue here: Make 'Search' remote and everything else (sorting, pagination, etc) local in jqGrid

Multiple datatables per page

I have multiple data tables per page, ranging from 4 to 8 ish.
All the tables have different settings. All the data is gotten via sAjaxSource (a javascript array).
My question boils down to:
Solution 1)
Should I have one seperate URL for each table? This seems to work, but means a full page load takes a lot longer.
Solution 2)
Have one same link for all the tables (and have seperate array name), so its only 1 download.
My questions are as follows:
Is there any recommmended solution for multiple data tables per page, that's best practice in terms of 1 or multiple links to get the javascript arrays.
If you provide the same ajax link to multiple datatables the browser seems to download them once per table instead of 1 time for all tables. Is this per "design" or a fault in my code?
Side note: I have checked http://www.datatables.net/examples/basic_init/multiple_tables.html and search the documentation but did not learn anything about the above questions.
In the case you described above, I would not rely on browser cashing, instead I would get data with my own single Ajax request. Store it in a local variable and for different tables use 'aaData' option.
var mydata;
$.ready(function(){
$.get("source/file.php", function(data){
mydata = data;
$('#table1').dataTable({ "aaData": mydata[0] });
$('#table1').dataTable({ "aaData": mydata[1] });
}, 'json');
});
but in the end solution depends on your needs, maybe you'll need lots of data, maybe it ll require paging and would be better off with multiple 'source' files with differed loading options etc.
The fact that the browser download the file only the first time when you provide the same link is, I think, due to the browser caching capabilities and has nothing to do with DataTables or your code. The browser put the content in its cache the first time and then serves it from there.
You can use this fact to your advantage by using the sAjaxDataProp option. I'm thinking something along these lines :
$('#table1').dataTable( {
"sAjaxSource": "sources/data.txt",
"sAjaxDataProp": "table1"
} );
$('#table2').dataTable( {
"sAjaxSource": "sources/data.txt",
"sAjaxDataProp": "table2"
} );
[ ... ]
$('#tableN').dataTable( {
"sAjaxSource": "sources/data.txt",
"sAjaxDataProp": "tableN"
} );
This will tell DataTable to look for a specific javascript array in the loaded content. Obviously, the data.txt file must contain the declaration of each table.
If you want to be sure that the browser do only one request, you could also load the data by an other means, a jQuery AJAX function for example, and then initialize the DataTables with an javascript array :
$('#table1').dataTable( { "aaData": array1 } );
$('#table2').dataTable( { "aaData": array2 } );
$('#tableN').dataTable( { "aaData": arrayN } );
I hope this will help :)

Categories