jqGrid: Sorting local data clears grid - javascript

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

Related

Pagination is not searching for records and not sorting my columns

I'm using the jQuery pagination plugin but I'm not able to get my data to be searched or sorted by columns.
I've searched for the documentation and also watched some videos explaining how to perform this procedure, but without success.
Right now my code looks like this:
dtAjax = $('#' + pTabela).DataTable(
{
"order": [[1, 'desc']],
responsive: true,
pageLenght: 50,
searching: true,
processing: true,
serverSide: false,
deferLoading: pTotalRegistros
}
My server Side necessarily needs to be "true", otherwise the pagination will not work properly.
However, when I leave the serverSide as "true", the functionality of searching and sorting the columns is not working, only when the serverSide is set to "false".
I have no idea how to solve this anymore, in case someone can save me..

Disable server-side processing for sort

I'm using of DataTables for show information in a table and I've enabled server-side load (I need that just for load data and pagination) and I don't need to search or sort by server side and I need default search and sorting (jQuery) for my table.
How can I do that ?
var table2 = $('#datatable-buttons2').DataTable({
"serverSide": true,
"processing": true,
"asSorting": ['desc', 'asc'],
"ajax": {
'type': 'POST',
'url': 'test.php?nowsearch=1',
'data': {
inputaz: $("#inputaz").val(),
inputta: $("#inputta").val(),
inputkey: $("#inputkey").val()
}
},
"columns": [{
"data": "group_name"
}, {
"data": "sender"
}, {
"data": "date"
}],
});
Maybe you can do this, customizing data retrieved in Javascript, but this is not useful.
If you sort your items in clientside with serverSide: true, it will be sorted the current retrieved data only, not based in all dataset in your database (if you actually limit results, if you don't, then use directly serverSide: false witch will retrieve all records).
For example, if you have 1000 records, you only get the data of first 10 of then only, not all (10/25/50/100). If you sort locally by age, it will sorted the retrieved 10. Then, if you go to the next page, you will notice the 2nd page is not sequential from the 1st page.
That's why you must to code your sorting/search in your back-end language when you use serverSide: true: in there you will sort first and then you return 10 records sorted.
That's the idea for this option.
Anyway... You can have pagination for client-side (serverSide: false) too by using paging option. But you need to be aware about performance.
In short, if you will handle many records, you should keep using server-side and code the sorting/search/pagination/etc from your back-end an return corresponding data. Is not so hard. You can play with parameters sent to achieve this.

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.

jqGrid: reload data from json-string

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).

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