So I'm using Datatables.JS to create a table of results returned from a MySQL database. When I return the results I'm trying to display them in DESC order. I have tried using ORDER BY DESC in my MySQLi query, this does return the results in the correct order, however when datatables is reading the results it's displaying them in some random order. So I've tried playing with the datatable settings to sort by my ID column but keep that column hidden. Whenever I attempt to add any code to handle the sorting, the sorting issue itself becomes resolved but all my pagination and buttons such as the buttons that allow the user to select which columns they would like to view just disappear. Below is the JS I'm using to select the features and setup I need for this datatable, can anyone show me how to add sorting by the ID column DESC into this without breaking it?
$(document).ready(function() {
$('#datatable').DataTable();
//Buttons examples
var table = $('#datatable-buttons').DataTable({
pageLength: 20,
lengthChange: false,
searching: false,
buttons: ['copy', 'excel', 'pdf', 'colvis']
});
table.buttons().container()
.appendTo('#datatable-buttons_wrapper .col-md-6:eq(0)');
} );
Adding ordering: and then selecting the column and defining the order seems to break all the other settings, I lose my pagination and default results length as well as all control buttons on the page.
$(document).ready(function() {
$('#datatable').DataTable();
//Buttons examples
var table = $('#datatable-buttons').DataTable({
pageLength: 20,
lengthChange: false,
searching: false,
buttons: ['copy', 'excel', 'pdf', 'colvis'],
order: [[ 1, desc ]]
});
table.buttons().container()
.appendTo('#datatable-buttons_wrapper .col-md-6:eq(0)');
} );
I have no idea why this solutions works and I still don't understand what caused the original problem but I did find a working piece of code posted under a loosely relevant problem on another forum. I combined that code with what I had already and it solved my problem. Hopefully this helps someone else out who may encounter the same issue.
$(document).ready(function() {
$('#datatable-buttons').DataTable( {
pageLength: 20,
lengthChange: false,
searching: false,
ordering: true,
order: [[ 3, 'DESC' ]],
dom: 'B1frtip',
buttons: [
'copy',
'excel',
'pdf',
'colvis'
]
});
table.buttons().container()
.appendTo('#datatable-buttons_wrapper .col-md-6:eq(0)');
});
Just wanted to mention this JS was for a datatable that's part of the Fonik Bootstrap Admin Template.
I'm upgrading jqgrid to the latest stable build of free-jqgrid (4.15.2) and the grid always shows a right-side gap where the scollbar will never need to be. It appears as though some of the usage has changed since the last developer updated the library and might be ahead of the documentation. I've looked at other questions in SO and:
I've tried manually stylling the grid, which did not help and served only to complicate matters.
I've tried setting scrollOffset:0 (with and without a height set in both percentatge and a static int) and it has not removed the scrollbar area
Other helpful info:
* We're manually resizing the grid to it's container on resize event and on initial draw. This code seems to have little effect now
I'm seeing the unsightly gap every time i set up a grid in a similar fashion to the following:
var grid_data = {
altRows: true,
data: [],
datatype: 'local',
sortable: false,
width: (bodyWidth() - 14),
rowNum: 10000,
colNames: [],
ondblClickRow: function() {
onGridDblClickRow();
},
onSelectAll: function() {
onGridSelectAll();
},
gridComplete: function() {
doGridComplete();
}
},
onRightClickRow: function( rowId ) {
doRightClick(rowId);
}
},
onSelectRow: $.proxy( onGridSelectRow, this ),
colModel: column_info_array,
multiselect: true,
multiselectWidth: 22,
viewrecords: true,
height:'100%',
scrollOffset:0,
}
The following fiddle shows the same problem in more reduced code
http://jsfiddle.net/catbadger/mhvzerdg/8/
When I use fixed column in JQuery Datatable it doesn't work properly if I resize the window.
If I remove scrollX from options, it appears just fine however fixedColumn feature doesn't work then.
See my options below:
$(document).ready(function() {
$('#example').DataTable( {
scrollY: 300,
scrollX: true,
scrollCollapse: true,
paging: false,
fixedColumns: true,
} );
} );
Link To Jsfiddle
Just Add width="100%" in your table tag.
It should be working by doing this.
I have the following setup for jQgrid 5.1.0:
<div id="grid_container">
<table id="grid"></table>
<div id="gridpager"></div>
</div>
<script type="text/javascript">
$.fn.fmatter.btnFormatter = function (cellValue, options, rowData, addOrEdit) {
var btn =
'<a href="#">' +
'<img class="api_button" data-id="' + options.rowId + '" src="/images/icons/16x16/view.png" alt="Show API Response data" title="Show API Response data" />' +
'</a>' +
'<a href="#">' +
'<img class="error_button" data-id="' + options.rowId + '" src="/images/icons/16x16/view.png" alt="Show errors" title="Show errors" />' +
'</a>';
return btn;
};
$(function () {
$("#grid").jqGrid({
url: '/sf/api-logs',
datatype: "json",
colNames: {{ colNames|raw }},
colModel: {{ colFormats|raw }},
width: 980,
height: 300,
pager: "#gridpager",
toppager: true,
hoverrows: true,
shrinkToFit: true,
autowidth: true,
rownumbers: true,
viewrecords: true,
rowList: [10, 20, 50, 100],
data: [],
rownumWidth: 50,
sortable: true,
jsonReader: {
root: 'rows',
page: 'page',
total: 'total',
records: 'records',
cell: '',
repeatitems: false
},
loadComplete: function (data) {
if (data.records === 0) {
$("#load_grid").addClass("info_msg").html($("<span>", {
"class": "grid-empty",
"text": "No results were found."
})).delay(800).fadeIn(400);
}
}
}).on('click', '.api_button', function () {
var apiResponseContent = $('#apiResponseContent');
$.ajax({
type: "GET",
url: '/sf/api-logs/api-response',
data: {id: $(this).data('id')},
dataType: 'json',
success: function (data) {
if (typeof data[0].error !== 'undefined') {
apiResponseContent.text(data[0].error);
}
apiResponseContent.text(data[0].apiResponse);
$('#api_dialog').dialog('open');
}
});
return false;
});
$('#api_dialog').dialog({
autoOpen: false,
width: 600,
height: $(window).height() * 0.9,
modal: true,
buttons: {
Ok: function () {
$(this).dialog('close');
}
}
}).show();
});
</script>
But as the image below shown the pagination is not working and the small icon for refresh the grid is not being displayed either, what I am doing wrong here?
UPDATE
I have managed to show the refresh button by adding the following code:
$('#grid').jqGrid('navGrid', '#gridpager', {
edit: false,
add: false,
del: false,
search: false,
refresh: true,
refreshstate: "current"
})
But it only appears on the #gridpagger what about if I want it also on the top bar?
Here is an example of the data returned by the server: https://gist.github.com/reypm/b1d2a303ba471261e55d72bbef099b74
You reported about two problems: pagination not working and the Refresh button appears on the bottom pager only (not on the top-pager).
The problem with Refresh button seems be mostly simple. You use commercial Guriddo, which probably still have the same logic of working with pagers like jqGrid 4.7. Old jqGrid has two pager options: pager and toppager, which values have to be specified in different ways. Working with toppager is easy: one can add toppager: true option and jqGrid will generate the top-pager div itself and to replace the value of toppager from true to the id selector of new pager. It will be toppager: "#grid_toppager". On the other side, to create the pager on the bottom of the grid one have to create somewhere on the HTML page dummy div, like <div id="gridpager"></div> and to use pager parameter in the form pager: "gridpager". jqGrid will move the div on another place inside of the grid and to fill it with data. Other methods like navGrid, inlineNav, navButtonAdd have to use #gridpager or "#grid_toppager" as parameter to create the navigator bar and to add buttons to the bar. Thus you have to use the code like
$('#grid').jqGrid('navGrid', '#grid_toppager', {
edit: false,
add: false,
del: false,
search: false,
refreshstate: "current"
});
or
var $grid = $('#grid'),
topPagerSelector = $grid.jqGrid('getGridParam', 'toppager');
$grid.jqGrid('navGrid', topPagerSelector, {
edit: false,
add: false,
del: false,
search: false,
refreshstate: "current"
});
to create the navigator bar on the top-pager and to add the Refresh button to it. Alternatively you can use cloneToTop: true option of navGrid to add the same pagers to both pagers:
$('#grid').jqGrid('navGrid', '#gridpager', {
cloneToTop: true,
edit: false,
add: false,
del: false,
search: false,
refreshstate: "current"
});
You can't use the option if you want to have only one top pager. You will have to use '#grid_toppager' with navButtonAdd method.
I develop free jqGrid fork of jqGrid. I simplified the behavior already in the first version of free jqGrid published in the 2015: see the wiki article. One can use pager: true in the same way like toppager: true and one can skip pager parameter in navGrid, inlineNav, navButtonAdd. The usage of navGrid could be
$('#grid').jqGrid('navGrid', {
edit: false,
add: false,
del: false,
search: false,
refreshstate: "current"
});
to add the navigator buttons on all pagers of the grid (top, bottom or both).
It's only one small difference between free jqGrid and Guriddo jqGrid. There are hundreds of other changes. I recommend you to consider to migrate to free jqGrid even if you payed Guriddo jqGrid license. I'd recommend you to read the page with the base information about the usage of free jqGrid.
The paging of data don't work because the response from your server is wrong. It looks like
{
"page": 1,
"total": 0,
"records": 67,
"rows": [
{ "id": "590a363477336501ad44ab02", "dataObject": "Account", ...},
...
{ "id": "590c97197ad70f00575a310a", "dataObject": "AgreementHistory", ...}
]
}
You use datatype: "json" option without loadonce: true option, which corresponds server side paging. It means that jqGrid send to url requests with rows and page parameter. The first request, which send jqGrid will contains page=1&rows=20 (20 is the default value of rowNum parameter of jqGrid) and the server have to return 20 or less rows (return only one requested page of data). Additional total and records property informs jqGrid about the total number or pages and records. Based on the value of total parameter jqGrid will disable pager buttons and the user will be not able to make paging correctly.
One the other side, your server response contains wrong value of total property and all 67 rows instead of 20 requested rows. Other 47 rows of the serve response will be just ignored by jqGrid.
If you have scenario, where the total number of records is not large (like 67 in you case), then it's recommended to add loadonce: true option (and forceClientSorting: true additionally in case of usage free jqGrid) and to modify the server response to
[
{ "id": "590a363477336501ad44ab02", "dataObject": "Account", ...},
...
{ "id": "590c97197ad70f00575a310a", "dataObject": "AgreementHistory", ...}
]
with all rows of the grid. jqGrid will fill internal data parameter, it will change datatype to "local" automatically after the first loading the data. As the result paging, sorting and filtering/searching (try filterToolbar or search: true of navGrid) locally without any additional communication to the server. It essentially simplify the server code and improves the performance of jqGrid. Even relatively large number of rows can be processed very quickly if you use small enough page size (like rowNum: 20 or rowNum: 10). You can try the demo with 60000 rows, 15 columns and 25 rows per page. You can test the time of paging, sorting and filtering.
I'm using Datatables with Scroller plugin and server-side loading. When data are loaded, header columns are resized and often (not always) don't fit to inside columns.
Picture of a situation (http://i.stack.imgur.com/J3zMz.png):
Relevant datatables setting code:
"sScrollY" : window.innerHeight - 270,
"bServerSide" : true,
"sDom" : "frtiS",
"bProcessing" : true,
"bDeferRender" : true,
"bAutoWidth" : true,
"oScroller" : {
"rowHeight" : 33,
"autoHeight" : false,
"serverWait" : 100
},
Is there any way how force header columns to always fit the content (and vice versa)?
Thanks.
try
$(window).load( function () {
$('#myTable').dataTable().fnAdjustColumnSizing( false );
} );