asked on
How do I implement "drawCallback" in Datatables and why does it work?
Here's the code I've been using for my Datatables:
$(document).ready(function () {
$('#dtOrderExample').DataTable({
"order": [[ 1, "asc" ]],
"pageLength" : 10,
"ordering": true,
"paging": true,
"searching": true,
"info":true,
"columnDefs": [ {
"targets": 'no-sort',
"orderable": false
}]
});
$('[data-toggle="tooltip"]').tooltip()
});
Just now I realized that the tooltips don't work like they should if I do any kind of sorting on the table itself.
Apparently, this is a known problem. According to https://stackoverflow.com/questions/39240361/datatables-and-bootstrap-tooltips, every time you redraw the table, you have to reinitialize the tooltip functionality.
This puts me in some uncharted territory. While the solution seems simple enough, I can't get it to work and I'm interested in knowing WHY "drawCallBack" works and what it is.
Also, I need to some guidance on this piece. This is what the above URL recommends, but I'm implementing incorrectly and I'm not sure what I'm doing wrong:
$(document).ready(function () {
$('#dtOrderExample').DataTable({
"order": [[ 1, "asc" ]],
"pageLength" : 10,
"ordering": true,
"paging": true,
"searching": true,
"info":true,
"columnDefs": [ {
"targets": 'no-sort',
"orderable": false
}]
});
"drawCallback": function(settings) {
$('[data-toggle="tooltip"]').tooltip();
}
});
The error is "Unexpected token." It's referring to a colon (:) on this line:
"drawCallback": function(settings) {
$('[data-toggle="tooltip"]').tooltip();
}
Where am I blowing it and, assuming this is the right way to do things, why does it work?
Scott has already provided the fix for your problem, so the points belong to him, but I'll try and explain the reasoning behind it.
When you call the DataTable() method on an element, you have the ability to pass in various options, and these options are passed in as properties of an Object. In JS, an Object is defined using the curly brackets. Each property is an option, and if you look at the documentation, it will tell the valid values for each property - could be a string, could be a number, could be an array, could be a callback (a function that will be called at some point).
Effectively you'd do something like this:
let myOptions = {
optionName1 : "Option Value",
optionName2 : 123,
optionName3 : true,
optionName4 : function(x) { alert("I'm a callback") }
}
$('#someTable').DataTable(myOptions);
If you look closely at your code, you'll see that the Options object finished before the drawCallback line// this is the options Object
({
"order": [[ 1, "asc" ]],
"pageLength" : 10,
"ordering": true,
"paging": true,
"searching": true,
"info":true,
"columnDefs": [ {
"targets": 'no-sort',
"orderable": false
}]
});
// and this is just tagged on - hence the error:
"drawCallback": function(settings) {
$('[data-toggle="tooltip"]').tooltip();
}
Hope that all makes sense$(document).ready(function
$('[data-toggle="tooltip"]
});
So, that will fire the tooltip() code when the document is first ready. It works because at that point, the [data-toggle="tooltip"] element exists in the DOM. Once DataTables is initiated and re-drawn (sorted / refreshed), the [data-toggle="tooltip"] is re-created, but the tooltip() event isn't fireed again because it only fired when the document was first ready.
So --- you need to re-call it each time the DataTable is redrawn, and we have a function that is fired every time a redraw happens - you define it with the drawCallback property
ASKER
Chris, here's what I'm hearing:
When DataTables creates a table, it's referred to as having "drawn" it (https://datatables.net/reference/option/drawCallback). The tooltip dynamic is something that needs to be coded as an option within the Datatables syntax because of the way it represents a "callBack," or, to use DataTables nomenclature, a "drawCallback."
A callback function is executed after the current effect is 100% finished (https://www.w3schools.com/jquery/jquery_callback.asp). Without placing the tooltip dynamic within the list of DataTables options / properties, something is going to go south and that's why I was running into either a performance issue or an outright error.
Correct?
Thank you!
First Datatables has tooltip, toggle and other features that usually get conflict with custom code and/or with Bootstrap. So always be carefull when use this with your custom code, always use what Datatables offer first.
I'm using Datatables a lot and I never use the tooltip, I do prefer just to use the title alone but in both case title cause issue in some setup with responsive and other plugins (this may have been fixed recently), so I try to avoid it.
The problem you had is that you called the function outside the Datatables using the wrong method.
Here is the correct method to do it from outside, this is the code I provided for this
$('#example').on('draw.dt', function () { $('[data-toggle="tooltip"]').tooltip(); });
You may need to call it from outside in some scenario depending how you load the table and if the table is dynamic or not.
Usually we specify the container for example body.
I know this is working without it but this can prevent issues depending of the other code and plugins
So I recommend to specify it.
drawCallback: function () {
$("[data-toggle='tooltip']").tooltip({
container: 'body'
});
Now from the code example to display the tooltip using Ajax and external data from txt file.
This set the tooltip for the column
{ "data": "name",
createdCell: function (td, cellData) {
$(td)
.attr('data-toggle', 'tooltip')
.attr('title', '')
.attr('data-placement', 'top')
.attr('data-original-title', 'Name');
},
and this call the function drawCallback: function () {
$("[data-toggle='tooltip']").tooltip({
container: 'body'
});
}
ASKER
ASKER
If I'm not mistaken, you both recommended the same thing, yes?
That's why I'm giving you both credit, but I do want to make sure that I have barked up the correct tree.
Lenamtl, I used your code that you had on your live demo, but (and this is for either one of you), why does it work?
From what I could gather from Google, when DataTables does a search, it refreshes itself in a way where any tooltip functionality is going to be compromised. How does "drawCallback" fix that?
Thanks!
This is what resulted in charred dragon flesh (the dragon has been slayed...)!
Open in new window