Hello i have created a table using the jquery datatable framework to display data.
automatically my datables are sorted into a form in which i do not want
so i did some research on how to disable sorting and then i get sorting disabled.
the problem now is when i disabled sorting i get a funny error :
"DataTables warning: table id=datatable - Cannot reinitialise DataTable. For more information about this error, please see http://datatables.net/tn/3"
so i do another round of research on why i am having this problem.
the problem is i am calling the dataTable() function twice on my page
so the solution should be to only call it once.
the second problem i have is i dont know where the first function has been called.
Reason : i am making use of a template and it does not state explicitly where this is defined.
how can i get rid of this error? is there any method.
please see my implementation for disabling sorting below which works for sorting but triggers that error
$(document).ready(function() {
$('#datatable').dataTable({
"bSort": false,
"bDestroy": true
});
});
what i am trying to achieve is display my datatable without sorting
Thanks
You need to destroy the existing DataTable before re-initializing it:
$(document).ready( function() {
if ( $.fn.DataTable.isDataTable( '#datatable' ) ) {
$( '#datatable' ).DataTable().destroy();
}
$( '#datatable' ).dataTable( {
"bSort": false,
"bDestroy": true
} );
} );
Related
I have a jQuery DataTable I am using to load my data. However I am struggling to export huge number of rows ex 15-20k rows.
$('#example').DataTable(
{
dom: 'Bfrtip',
buttons: [
'excel'
],
initComplete: function(){
$('.buttons-excel').style('display', 'none')
$('#custom-excel-button').click(function(){
$('.buttons-excel').trigger('click')
})
}
});
I have a custom button <button id='custom-exel-button' />
When user clicks on this button I want to trigger export functionality It works fine but I am having some UI issues. When its a huge volume, it just hangs on the button.
Instead I want to show some sort of loading icon when an export is happening.
Is there a callback I can use to know when export is completed? So I can just load a loader icon when user clicks the button then hide the loader on the callback.
You can use a custom button action to do this.
In the example below, I am using the SweetAlert2 library, just for convenience in this basic demo.
<script src="https://cdn.jsdelivr.net/npm/sweetalert2#10.15.7/dist/sweetalert2.all.min.js"></script>
The button code in the DataTable:
buttons: [
{
text: 'Excel',
action: function(e, dt, node, config) {
var that = this;
Swal.fire('Data is being loaded...');
setTimeout(function() {
$.fn.DataTable.ext.buttons.excelHtml5.action.call(that, e, dt, node, config);
Swal.close();
}, 1000);
}
}
]
The excelHtml5.action.call() function is how I manually trigger the Excel file creation in this case, instead of the more usual appraoch.
(Having said that, I completely agree with the comments in the question: This is a job which should really be performed on the server. I don't see any reason to show this much data to the user in a web page, even prior to the Excel export. I imagine the browser and DataTables take quite some time to process/display the raw data, also.)
I use bootstrap for tabs on my pages. Inside these tabs are JQuery Data Tables. For some reason when a user clicks a tab after the page has loaded the data table's headers do not allign with the rows.
If I click one of the headers (the button that orders the column) then the columns fix themselves. Can anybody help me out here? I've tried several CSS and Javascript "hacks" to fix this.
Here's where I initialize my data table:
$( ".dynamic-table" ).DataTable({
"scrollY": 450,
"scrollCollapse": true,
"lengthMenu": [[10, 50, 500, -1], [10, 50, 500, "All"]]
});
SOLUTION
Use columns.adjust() API method to recalculate columns widths.
From the manual:
Call it when the table becomes visible if hidden when initialized (for example in a tab) or when the data changes significantly.
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e){
$($.fn.dataTable.tables(true)).DataTable()
.columns.adjust();
});
DEMO
See this jsFiddle for code and demonstration.
LINKS
See jQuery DataTables – Column width issues with Bootstrap tabs for solution to the most common problems with jQuery DataTables and Bootstrap Tabs.
I found a solution. This will sort the first th programatically on tab click thus fixing the unalligned headers. It does it twice in order to bring the order back to way it was originally.
/* FIX FOR COLUMNS BEING UNALLIGNED */
$(document).on( 'shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
var activeTabPanel = $('.tab-pane.active');
activeTabPanel.find("th:first").click();
activeTabPanel.find("th:first").click();
});
How can I determine if DataTables() is done rendering in version 1.10 and above? Is there a callback somewhere I can set to a function. I'd like to hide my table until DataTables is finished and then reveal it once it is done loading.
With version 1.10, I haven't come across a callback, and I think a lot of the old callbacks are now deprecated as their links redirect me to legacy.datatables.net
You can use init.dt event as follows:
$('#example').on('init.dt', function(e, settings, json){
console.log( 'Table initialisation complete: '+new Date().getTime() );
});
$('#example').dataTable();
From the manual:
init event is called when your table has fully been initialised, data loaded and drawn, particularly when using an ajax data source.
NOTES
If you're going to hide/show the table, you would need to use columns.adjust() API method to recalculate column widths once table becomes visible.
For example:
$('#example-container').hide();
$('#example').on('init.dt', function(e, settings, json){
$('#example-container').show();
$(this).DataTable().columns.adjust();
});
$('#example').dataTable();
I am working on jQuery's jqGrid and I am not using paging in my jqGrid. My code fetch more than 1000 rows data and all data shows in jqGrid without paging and use loadonce: true property. Now my requirement is that when user sort any column it takes 3-5 seconds to sorting data so i want to show at that time loading image. I wrote
beforeRequest: function () { jQuery(".imgLoading").show(0);},
gridComplete: function () {jQuery(".imgLoading").hide(0);}
these 2 events and it works fine when data comes with server and manipulating with server.
But I want to sorting on client side by using loadonce: true and want to show loading image also but I don't know on which event I will write down image show hide code.
Please tell me the name of BeforeSortEvent and AfterSortEvent of jqGrid.
I checked on this URL : http://www.trirand.com/jqgridwiki/doku.php?id=wiki:events but didn't find right event.
Please help me out.....
Try:
onSortCol: function(index, iCol, sortorder) {
jQuery(".imgLoading").show(0);
},
gridComplete: function() {
jQuery(".imgLoading").hide(0);
}
EDIT
Since you said the alert() fires off, I'm thinking your problem is in the way you are showing/hiding those .imgLoading elements.
Try:
onSortCol: function(index, iCol, sortorder) {
alert("I'm about to SHOW the loading message");
$(".imgLoading").show();
},
gridComplete: function() {
alert("I'm about to HIDE the loading message");
$(".imgLoading").hide();
}
Be sure those two alert()'s fire off, and if they do, then something is still off with those .imgLoading elements you are trying to show/hide.
I have an issue with jgrid's tableToGrid. I have three nested tabs (inside an another tab) that generate out of the following three list items
<div id='sub_nav_menu >
<ul>
<li><a href='workorders.php'/>Open WorkOrders</a><li>
<li><a href='workorders.php?status=overdue'/>Stale WorkOrders</a><li>
<li><a href='workorders.php?status=closed'/>closed WorkOrders</a><li>
</ul>
</div>
jQuery-ui will create a content div for each one of these links in an unobtrusive manner, where the result obtained from the server will be shown inside that div as a table, with the same class selector of the other tables obtained from selecting the other siblings tabs. The tables will be shown inside the dynamically created div, which associate with each of these tabs. The table looks like this:
<table class='result-table'>
<thead>...</thead>
<tbody>You know what's here ...</tbody>
</table>
and the jquery ui code which creates the grid is this
$('#nav').tabs({
load: function() {
// first: load the inner tabs
$('#sub_nav_menu').tabs({
load: function (event,ui) {
// second: load jqGrid stuff after loading the tabs content
tableToGrid(".result-table:eq(" + ui.index + ")",{
defaults : {
recordtext: "View {0} - {1} of {2}",
emptyrecords: "No records to view",
loadtext: "Loading...",
pgtext : "Page {0} of {1}"
},
loadonce: true,
rowNum: 10,
caption: 'Showing "Open Work orders"'
});
} //inner nav 'load' function
});
} //upper nav 'load' function
});
The table is converting properly to a jqGrid, the data of the original table is carried over properly inside the plugin code in a "data" array; however, the plugin fails when it reaches to the point of
jQuery(this).jqGrid(jQuery.extend({
datatype: "local",
width: w,
colNames: colNames,
colModel: colModel,
multiselect: selectMultiple
//inputName: inputName,
//inputValueCol: imputName != null ? "__selection__" : null
}, options || {}));
Which is followed by the code
$.fn.jqGrid = function( pin ) {
if (typeof pin == 'string') {
//var fn = $.fn.jqGrid[pin];
var fn = $.jgrid.getAccessor($.fn.jqGrid,pin);
if (!fn) {
throw ("jqGrid - No such method: " + pin);
}
var args = $.makeArray(arguments).slice(1);
return fn.apply(this,args);
}
return this.each( function() { // it failes where the "chaining" happens
if(this.grid) {return;}
However, the code fails where the "chaining" happens with the error code
Uncaught Error: Syntax Error, unrecognized expression "#"
It seems it's related to the 'class' vs. 'id' selector as when I change the table selection to 'id' it works.
I am just wondering if this could be a bug in the plugin of jqGrid. Even if it's the case, what would you suggest as a different way to go around this problem. I was thinking of generating different ids for each one of the tables, but I am just annoyed with the issue of not being able to use tables class as a selector!
The jQuery version is 1.7.1,
The jQuery-UI 1.8.17
The jqGrid is 4.3.1
Thanks alot!
Workaround
I managed to make it work with server-side generated ids for easier reference and then doing a switch at the client-side on these ids as they are previously known. However, I see this method as being inefficient because it don't deal with general case selectors, but rather specific ones and do not address the real problem.