I am trying to run a report with two tabulator tables. One main table, then on click of a row it will populate a modal. All the html part works and the jquery (JS) works. I have a success function on my ajax call to set the data in the modal. But it does not seem to be waiting for the ajax to return the data. See code below. I can see the data in the console.log so the console.log seems to be running its just not pushing to the table. If I run a function to set the data manually from the console it works. So not really sure whats going on.
var CatVolumetable = new Tabulator("#myreport", {
//height:205, // set height of table (in CSS or here), this enables the Virtual DOM and improves render speed dramatically (can be any valid css height value)
placeholder:"Select Year-Month to populate Data",
layout:"fitColumns", //fit columns to width of table (optional)
columns:[ //Define Table Columns
{title:"Category Name", field:"Category_name", align:"left"},
{title:"State", field:"State",align:"center"},
{title:"Max Quantity",field:"maxQuantity", align:"left"},
],
rowClick:function(e, row){ //trigger an alert message when the row is clicked
var state = row.getData().State;
//getStoresByState(state);
$('#drilldown').modal('toggle');
let myUrl = 'http://localhost:3000/view_state_category_volume_drilldown/'+state;
$.ajax({
//$.ajax({
url: myUrl,
method: 'get',
dataType: 'json',
success: function(data){
console.log(data);
ddtable.setData(data);
}
});
var ddtable = new Tabulator("#drilldownTable", {
//height:205, // set height of table (in CSS or here), this enables the Virtual DOM and improves render speed dramatically (can be any valid css height value)
//ajaxURL:""
placeholder:"No Data Available",
layout:"fitColumns", //fit columns to width of table (optional)
columns:[ //Define Table Columns
{title:"Manager_email", field:"Manager_email"},
{title:"Manager_name", field:"Manager_name", align:"left"},
{title:"Store_num", field:"Store_num"},
{title:"Street_address", field:"Street_address", align:"center"},
{title:"City Name", field:"City_name", align:"center"},
],
});
SOLUTION:
I figured out the problem is that the data must be loaded after the modal is toggled (i.e. after it is visible). If I load data on the show event listener it works perfectly. Below is code with bootstrap.
$("#drilldown").on('shown.bs.modal', function (e){
///Ajax call with success handler to load data
})
If the API is too fast for your second tabulator table
Check this post
.Use below code to set Data after drilldownTable is initialized
if ($("#drilldownTable").hasClass("tabulator")){
//element has class of .tabulator
}
Related
I have the tabulator plugin set up and working with my data. Currently, using the remote pagination feature but whenever the pagination buttons are clicked it loads the data and then scrolls to the top of the page. The pagination buttons do not contain href="#" so it shouldn't be trying to load a browser state.
The really odd thing is it is doing this behavior on any ajax call I make relative to tabulator. I used the setData function to load updated data and it scrolled to the top of the page again.
Here's a very simplified version of my code:
<div id="#tabulator"></div>
<script>
$("#tabulator").tabulator({
movableColumns: true,
layout: "fitColumns",
pagination: "remote",
paginationSize: 10,
ajaxURL: "rosterusers_tabulator_data-json.cfm",
ajaxParams: {/* url params here */},
columns: [/* columns set here*/]
});
/*then I have a modal dialog update event which calls the following*/
$("#tabulator").tabulator(
"setData",
"rosterusers_tabulator_data-json.cfm",
{/*url params here*/}
);
</script>
I don't think I'm doing anything bizarre here but each time the table data gets updated via ajax in anyway (page change, data change, filter change, etc.) it scrolls to the top of the page.
Here is solution for various scroll to top related issues. It involves extending the tabulator.js with two functions:
Tabulator.prototype.getVerticalScroll = function () {
var rowHolder = this.rowManager.getElement();
var scrollTop = rowHolder.scrollTop;
return scrollTop;
}
Tabulator.prototype.setVerticalScroll = function (top) {
var rowHolder = this.rowManager.getElement();
rowHolder.scrollTop = top;
}
Then get and set like this:
let pos = table.getVerticalScroll();
// do table management e.g. setColumns
table.setVerticalScroll(pos);
The replaceData function can be used to set data in the table without changing the scroll position:
$("#example-table").tabulator("replaceData", "rosterusers_tabulator_data-json.cfm")
I have several options for my JQuery datatable which will clear the DataTable and load new data via WebSockets. Therefore I clear the Table contents with fnClearTable()and a few moments later I get the new data via my WebSocket.
This can last up to a few seconds and in the meantime I would like to display a loading image in my DataTable. How can I achieve this?
My event handler which clears the DataTable:
/* On Daterange change (e.g. Last 3 Days instead of Last 24h) */
$('#profitList_dateRange').change(function() {
var dateRangeHours = $("#profitList_dateRange").val();
var jsonParamObject = JSON.parse(dateRangeHours);
// Clear table
var profitList = $('#profitList').dataTable();
profitList.fnClearTable(); // Now I want to show the loading image!
socket.emit('load-statistics', (jsonParamObject));
});
One way to achieve it is if you have 2 divs (I assume that your divs are properly styled to the content inside of them):
<div id="profitList"> your table content </div>
<div id="profitListLoading"> show loading here </div>
Then in your handler:
$('#profitList_dateRange').change(function() {
var dateRangeHours = $("#profitList_dateRange").val();
var jsonParamObject = JSON.parse(dateRangeHours);
// Clear table
var profitList = $('#profitList').dataTable();
profitList.fnClearTable(); // Now I want to show the loading image!
$('#profitList').hide();
$('#profitListLoading').show();
socket.emit('load-statistics', (jsonParamObject));
});
In your handling of loaded data you should ofc. revert the change
$('#profitList').show();
$('#profitListLoading').hide();
Make sure you have processing: true
$('#example').dataTable({
processing: true
});
Then add:
$('.dataTables_processing', $('#example').closest('.dataTables_wrapper')).show();
If you want to add a GIF image you can change the markup as follows:
$('#example').dataTable({
oLanguage: {
sProcessing: "<img src='https://d13yacurqjgara.cloudfront.net/users/12755/screenshots/1037374/hex-loader2.gif'>"
},
processing: true
});
DEMO: http://jsfiddle.net/0m6uo54t/2
processing:
Enable or disable the display of a 'processing' indicator when the
table is being processed (e.g. a sort). This is particularly useful
for tables with large amounts of data where it can take a noticeable
amount of time to sort the entries.
https://datatables.net/reference/option/processing
[UPDATE] bProcessing is the legacy option, the new DT code uses processing
I am using the tooltipster plugin tool where I got gantt chart drawn with some td given id.
So, which ever id is defined and the mouse over it will get ajax data and show accordingly.
Below is snippet of my codes. Issue here is that the tool tip only appear after few times I mouse the td. Thereafter, it works fine.
I can see, in my debug window, that ajax page is called and following error:
Tooltipster: one or more tooltips are already attached to this element: ignoring. Use the "multiple" option to attach more tooltips. jquery.tooltipster.min.js:1
$(document).ready(function () {
$('td[id]').tooltipster({
// content: 'Loading...',
functionBefore: function(origin, continueTooltip) {
// We'll make this function asynchronous and allow the tooltip to go ahead and show the loading notification while fetching our data
continueTooltip();
var idval=0;
// Next, we want to check if our data has already been cached
//if (origin.data('ajax') !== 'cached') {
$.ajax({
type: 'GET',
url: 'getDetails.php',
data:idval,
success: function(data) {
// Update our tooltip content with our returned data and cache it
//alert("Data is : "+data);
var finalData = 'Total Data : 300 <br> Total Completed : 200';
//alert("DATA");
//origin.tooltipster: $('<span>testst<strong>This text is in bold case !</strong></span>')
origin.tooltipster({
content: finalData,
multiple: true,
contentAsHTML: true
});
//origin.tooltipster({content: data,contentAsHTML: true}).data('ajax', 'cached');
}
});
//}
}
});
});
The Tooltipster plugin really should be initialised before all of this. Using the mouseenter enter to trigger it's initialisation every time a user hover's over a <td> element is not great practice and is the root problem to your issue. Ideally you would want to break it down into the following:
Find your <td> elements with id's defined.
Apply tooltipster to these elements.
Let tooltipster handle everything from there.
1. Finding your <td> elements
With the magic of jQuery you can fetch these with a clever use of selectors rather than querying a larger set with your initial implementation, gathered from the answers within the StackOverflow thread here, jquery get only all html elements with ids, we get:
$('td[id]')
This will fetch you all <td> elements with an id defined, be warned this could be a bit slow if you have an extensive table. Alternatively you can select, then apply a filter to narrow down your set:
$('td').filter(function(){
return $(this).attr('id') !== undefined;
});
Both will essentially do the same!
2. Applying tooltipster to these elements
I've not done much here since you had a lot of commented out code, so I've kept it the same, with some minor tweaks, here is my version of the "working code":
$('td[id]').tooltipster({
// content: 'Loading...',
functionBefore: function(origin, continueTooltip) {
// We'll make this function asynchronous and allow the tooltip to go ahead and show the loading notification while fetching our data
continueTooltip();
// Next, we want to check if our data has already been cached
//if (origin.data('ajax') !== 'cached') {
$.ajax({
type: 'GET',
url: 'getDetails.php',
data: $(this).attr('id'),
success: function(data) {
// Update our tooltip content with our returned data and cache it
//alert("Data is : "+data);
var finalData = 'Total Data : 300 <br> Total Completed : 200';
//alert("DATA");
//origin.tooltipster: $('<span>testst<strong>This text is in bold case !</strong></span>')
origin.tooltipster({
content: finalData,
multiple: true,
contentAsHTML: true
});
//origin.tooltipster({content: data,contentAsHTML: true}).data('ajax', 'cached');
}
});
//}
}
});
3. Letting tooltipster handle everything from here
Tooltipster (when intialised) is triggered by default when hovering over an element, this means your functionBefore will be run before this "hover" event, causing your AJAX request to be run each time, there is no need to do anything more thereafter :D
I hope this helps! :)
You can use this code :
var tooltipInstance;
$("body").on('mouseover', 'td[id]:not(.tooltipstered)', function(){
tooltipInstance = $(this).tooltipster({
//your code ...
});
tooltipInstance.tooltipster('open');
});
I have a working setup for data-tables and x-editable that allows a user to edit data inline in a table that gets loaded from the database. Once the page loads my code below fires and makes all the editable options editable, except it only seems to work for the first page of results. When you click next, change the number of results or do a search, any items that were not on the first page don't get made editable. I am assuming this is because data-tables hides the data that is not on the current page removing it from the document flow. How can I make sure all my data in the table is editable?
$(document).ready(function () {
$.fn.editable.defaults.mode = 'inline';
$('.LocatorID').editable();
$('.Title').editable();
$('.Latitude').editable();
$('.Longitude').editable();
$('.Website').editable();
$('.Address').editable();
$('.City').editable();
$('.State').editable();
$('.Zip').editable();
$('.Country').editable();
$('.Phone').editable();
});
First, move your x-editable setup into its own function:
function setupXedit() {
$.fn.editable.defaults.mode = 'inline';
$('.LocatorID').editable();
$('.Title').editable();
...
}
Then set so that you call the function on every draw:
$('#example').dataTable({
"fnDrawCallback": function( oSettings ) {
setupXedit();
}
});
Do like this: one $('.edit').editable(); inside Datatable fnDrawCallback and one outside .Datatable function
var table = $('#tbldivdsthietlap').DataTable({
"fnDrawCallback": function( oSettings ) {
$('.edit').editable();
}
});
$('.edit').editable();
I am working on an online music store. There are buttons like myplaylists, mydownloads etc...
On clicking on these buttons, a list of songs appears accordingly in a grid view.
The problem is that when I click on the buttons twice quickly the list appears two times like 1..4..8 1..4..8 and if I click thrice quickly it happens three times.The function that displays the list uses append() to add songs to the list.
These things happen only on Firefox
I cannot figure out the problem.
function fillMyMusicSongGrid
{
// code to fetch data from the database
embedSongGrid(.....);//displays the grid
}
embedSongGrid(.....)
{
//displays the grid
tableContent = '...............'
$(tableCont).appendTo('table#songList');
}
If I'm guessing correctly, pressing these buttons makes and Ajax call back to the server to get the information, probably as a JSON array. You then loop through these and append() them to the appropriate div. Either that or you get HTML and just append it.
Simply solution: just empty() it before you add it:
$.ajax({
...
success: function(data) {
$("#songlist").empty();
for (song in data) {
$("#songlist").append(...);
}
}
});
or
$.ajax({
...
success: function(html) {
$("#songlist").html(html);
}
});
Try
$(tableCont).empty();
$(tableCont).appendTo('table#songList');
instead of
$(tableCont).appendTo('table#songList');