jQuery Datatables Header Misaligned With Vertical Scrolling - javascript

I've posted this in the datatables.net forums, but after a week, still no response. Hopefully I can find help here...
I'm using datatables version 1.8.1 and am having nightmares over column header alignment with vertical scrolling enabled.
With the code posted below, the headers line up correctly in Firefox and IE8 and IE9, but Chrome and IE7 are off. I'm using a lot of datatables on this project, and this is a problem with every one. I'm desperate for help!
EDIT: I have figured out that this has something to do with setting the width of the table. The datatable takes the width of its container. If I set no width, everything lines up fine (but the table is too big for where I need it on the page). If I give the table's div (or a parent div somewhere higher up) a width at all, the headers don't line up properly.
Thanks!!
Screenshots:
www.dennissheppard.net/firefox_alignment.png
www.dennissheppard.net/chrome_alignment.png
www.dennissheppard.net/ie7_alignment.png
otable = $('#order_review_grid').dataTable({
'fnRowCallback': function (nRow, strings, displayIndex, dataIndex) {
return formatRow(nRow, dataIndex);
},
'fnDrawCallback':function()
{
checkIfOrderSubmitted(this);
},
'aoColumnDefs':
[
{ 'bVisible': false, 'aTargets': [COL_PRODUCT] },
{ 'bSortable': false, 'aTargets': [COL_IMAGE, COL_DELETE] },
{ 'sClass': 'right_align', 'aTargets': [COL_PRICE] },
{ 'sClass': 'center_align', 'aTargets': [COL_BRAND,COL_PACK] },
{ 'sClass': 'left_align', 'aTargets': [COL_DESCRIPTION] }
],
'sDom': 't',
'sScrollY':'405px',
'bScrollCollapse':true,
'aaSorting':[]
});
<table id="order_review_grid" class="grid_table" cellpadding="0px" cellspacing="0px">
<thead class="grid_column_header_row" id="order_review_grid_column_header_row">
<tr>
<td class="" id='sequenceNumber'>SEQ #</td>
<td class="grid_sc_header" id='statusCode'>Sc</td>
<td class="grid_sc_header" id='onOrderGuide'>O.G.</td>
<td class="grid_image_header" id='image'>Image</td>
<td class="grid_description_header" id='description'>Description</td>
<td class="grid_brand_header" id='label'>Brand</td>
<td class="grid_pack_header" id='packSize'>Pack</td>
<td class="grid_price_header" id='price'>Price</td>
<td class="grid_qtrfull_header" id='caseQuantity'>Full</td>
<td class="grid_qtrypart_header" id='eachQuantity'>Partial</td>
<td class="grid_refnum_header" id='referenceNumber'>Ref #</td>
<td class="grid_refnum_header"> </td>
</tr>
</thead>
<tbody class="">
<!-- loaded data will go here -->
</tbody>
</table>

I'm having the same problem here. It works fine (pixel-perfect column aligned) in Mozilla Firefox, Opera but not in Chrome 21.
Solution:
Like mentioned in this post http://datatables.net/forums/discussion/3835/width-columns-problem-in-chrome-safari/p1
Basically what is happening, is that DataTables is trying to read the
width of the table, that the browser has drawn, so it can make the
header match. The problem is that when DataTables does this
calculation on your page, the browser hasn't shown the scrollbar - and
hence the calculation is slightly wrong! The reason I suggest that
it's a Webkit bug, is that, even after DataTables has run through all
of it's logic, the scrollbar still hasn't been displayed. If you add
the following code you can see the effect of this:
console.log( $(oTable.fnSettings().nTable).outerWidth() );
setTimeout( function () {
console.log( $(oTable.fnSettings().nTable).outerWidth() ); }, 1 );
The interesting part is that after I added setTimeout and after it executed there was still one column not aligned. After adding "sScrollX": "100%",
"sScrollXInner": "100%" all columns were aligned (pixel-perfect).
Solution for Chrome/Chromium, works ofcource in FF, Opera, IE9:
$(document).ready(function()
{
var oTable = $('#mytable').dataTable(
{
"sScrollY": ( 0.6 * $(window).height() ),
"bPaginate": false,
"bJQueryUI": true,
"bScrollCollapse": true,
"bAutoWidth": true,
"sScrollX": "100%",
"sScrollXInner": "100%"
});
setTimeout(function ()
{
oTable.fnAdjustColumnSizing();
}, 10 );
});

I solved this problem by wrapping the "dataTable" Table with a div with overflow:auto
.dataTables_scroll
{
overflow:auto;
}
and add this JS after your dataTable initialization
jQuery('.dataTable').wrap('<div class="dataTables_scroll" />');
Dont use sScrollX or sScrollY, remove then and add a div wrapper yourself which does the same thing.

I had the problem and it turned out to be a side effect with my CSS. Try to disable all external css and see if the problem persists.

var table = $("#myTable").DataTable({
"sScrollY": "150px",
//"bAutoWidth": false // Disable the auto width calculation
});
$(window).resize( function () {
table.columns.adjust();
} );

if ( $.browser.webkit ) {
setTimeout( function () {
oTable.fnAdjustColumnSizing();
}, 10 );
}
Worked perfect for me!

I had a similar issue, but mine resizes to fit after searching or sorting or interacting with the table in a way to cause a redraw, tried the redraw...function but no luck had to improvise in the end. The funny fix I that worked for me was calling oTable.fnFilter( "x",0 ) and oTable.fnFilter( "",0 ) in this same order (search and clear search)... this works...lol.. :)

this might help you (not sure but i guess that its worth trying)
add this code to the page
if ( $.browser.webkit ) {
setTimeout( function () {
oTable.fnAdjustColumnSizing();
}, 10 );
}
taken from here
width columns problem in Chrome & Safari
Also, i guess it worth trying to define the columns in the constructor only instead of defining them in the (leave tag empty)

I also had this problem. After many different tries I tried the below and succeeded.
I tried adding label tag with the float property in the style attribute. Then it worked find.
For example:
<td class="" id='sequenceNumber'><label style="float:left;">SEQ #</label></td>

I had a problem where the data in the columns was too large to fit and there was no place in the data for a line break. My solution was to add a div with an overflow and a title attribute like this:
<td style="width: 110px;max-width:200px;"><div style="overflow:hidden;" title="#item.NewValue" >#item.NewValue</div></td>
This caused the table to settle down almost completely.

if you are using bootstrap:
.table {
width: 100%;
max-width: none; // >= this is very important
}

This is how I have got rid of this problem:
I use this generally to execute functions after a Ajax call has been completed
WaAjaxHelper = {
arr_execute_after_ajax: null,
add_function_to_execute_after_ajax: function (fun) {
if (typeof fun == 'function') {
if (!this.arr_execute_after_ajax) {
this.arr_execute_after_ajax = [];
}
this.arr_execute_after_ajax.push(fun)
return true;
} else {
alert('ERROR: WaAjaxHelper.add_function_to_execute_after_ajax only functions possible');
return false;
}
},
execute_after_ajax: function () {
if (this.arr_execute_after_ajax) {
$.each(this.arr_execute_after_ajax, function (index, value) {
try {
value();
} catch (e) {
console.log(e);
}
})
}
this.arr_execute_after_ajax = null;
}
}
$(document).ready(function () {
$.ajaxSetup({
async: true,
beforeSend: function (xhr) {
xhr.setRequestHeader("Accept", "text/javascript");
$('.blockUI').css('cursor', 'progress');
},
complete: function (jqXHR, textStatus) {
$('body').removeClass('waiting');
},
error: function (jqXHR, textStatus, errThrown) {
alert("Ajax request failed with error: " + errThrown);
ajax_stop();
}
});
$(document).ajaxStart(ajax_start).ajaxStop(ajax_stop);
});
ajax_start = function () {
// do something here
}
ajax_stop = function () {
WaAjaxHelper.execute_after_ajax();
}
in the view:
var tbl;
WaAjaxHelper.add_function_to_execute_after_ajax(function (){tbl.fnDraw()})
where tbl stores the datatable object.

Having the same problem in firefox,
I changed a little the script jquery like this (in jquery.dataTables.js version 1.9.4) :
line 3466 (v1.9.4) : nScrollHeadInner.style.paddingRight = "0px"; //instead of bScrolling ? o.oScroll.iBarWidth + "px" : "0px";
line 3472 (v1.9.4) : nScrollFootInner.style.paddingRight = "0px"; //instead of bScrolling ? o.oScroll.iBarWidth + "px" : "0px";
It works even after sorting and filtering.

I use bootstrap and I managed with this
<table id="datatable_patients" class="table table-striped table-bordered table-hover table-responsive" width="100%">
<thead></thead>
<tbody></tbody>
</table>

I had this problem with bootstrap 3 and the problem was related to left and right padding on my th and td elements that I added after the bootstrap styling was applied. Removing my left and right padding fixed the problem in my case.

We can handle this using css and minor changes in sDom.
Add following class in your css file
.scrollDiv {
max-width:860px; //set width as per your requirement
overflow-x:scroll;
}
replace your 't' in sDom attribute of table with <"scrollDiv"t> and remove scrollX attribute of table
Save and Enjoy ! :)

I found that the width would misalign in the first window scroll, so the solution is to, on the first scroll only request a new table draw.
const $table = $('#table').DataTable({ ... });
$(window).on('scroll', () => {
$(window).off('scroll');
$table.tables().draw();
});
Edit: Also works with a setTimeout function. This depends when the misaligning happens.
$table.tables().draw() is the key here.

I too faced the same issue. I solved it by removing 'sScrollY':'405px' from the datatable property and used fixed header.

JS
$('#<%=gridname.ClientID%>').dataTable( {
"paging": false
});
});
Then above your gridview add a div element as below.
<div style ="height:600px; overflow:auto;">
<asp:GridView ID="id" runat="server" DataKeyNames="key" ClientIDMode="Static" HeaderStyle-BackColor="#99ccff"
BorderStyle="Inset" BorderWidth="1px" CellPadding="4" HorizontalAlign="Center" AutoGenerateColumns="false" Width="98%" >
etc..
</div>

Not sure if I had the exact same problem. I was dealing with a very large table, 40+ columns, and was using horizontal and vertical scrolling. However, if the browser window was set so big that you could see the whole table, the column headings were left aligned and the table content was in the center.
I noticed in firebug that the table had gotten a width of 1352px through DataTables. Setting that to 100% made everything line up!

I know this is quite old thread, but I landed here when searching for the header alignment issue. Turned out I needed a different solution, so posting here so that someone will find it useful.
I just added following in my style block and it solved the issue:
.table {table-layout:auto !important;}
Seems that Datatables adds fixed layout, so adding this line made my headers align correctly with data when scrolling

After a long struggle I managed to tweak it:
add this after initializing the data table. Avoid adding "scrollY/scrollX",
and also avoid enabling "scrollCollapse"
$('#table_id').wrap('<div class="dataTables_scroll" />');
Add these to your CSS Styles.
.dataTables_scroll
{
position: relative;
overflow: auto;
max-height: 200px;/*the maximum height you want to achieve*/
width: 100%;
}
.dataTables_scroll thead{
position: -webkit-sticky;
position: sticky;
top: 0;
background-color: #fff;
z-index: 2;
}

Related

Center visualize.js div content on page

I have been trying to get a report that we have built with jasperreports and rendered via visualize.js to be centered horizontally on a page (regardless of the page or browser dimensions).
My current code is:
<!DOCTYPE html>
<html>
<head>
<script src="https://mobiledemo.jaspersoft.com/jasperserver-pro/client/visualize.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mootools/1.5.1/mootools-core-full-compat.min.js"></script>
<script type='text/javascript'>
window.addEvent('load', function() {
visualize({
auth: {
name: "joeuser",
password: "joeuser",
organization: "organization_1"
}
}, function(v) {
//render dashboard from provided resource
v("#container").report({
resource: "/public/Samples/Reports/06g.ProfitDetailReport",
scale: "container",
error: handleError
});
//show error
function handleError(err) {
alert(err.message);
}
});
});
</script>
<style>
html,
body {
height: 100%;
width: 100%;
margin: 0 auto;
background-color: #000000;
}
#container {
display: block;
width: 100%;
height: 100%;
border: 0px;
margin: 0 auto;
background: blue;
}
</style>
</head>
<body>
<div id="container"></div>
</body>
</html>
The following fiddle should show the current issue:
https://jsfiddle.net/g207h68x/
If you resize the result window, you can see that as the report is scaled (via the scale:"container" entry in the render function it sticks to the left of the screen.
I can't use any specific sizes for the <div> as each dashboard has their own unique dimensions depending on what is being displayed in the report or dashboard (some may be 300x500 and others may be up to 1920x1080).
I have tried to wrap the <div> inside flexboxes which didn't seem to help..unless I was not doing it correctly (entirely possible).
Another approach was to try and nest the div within a parent div, but that didn't seem to work either (again, I may have not done it correctly either).
I have also tried to make the <div> an inline-block, but that seems to throw off the scaling entirely for visualize.js as it reads the container dimensions (I think).
I looked into the visualize.js documentation, but there is really not much there for dynamic sizing and spacing on the page.
I even tried to put the <div> within a table...but that didn't seem to help as the table cells would just span across the page or container.
I did read somewhere that the JQuery UI can be used to further manipulate what visualize.js is doing, but I could not find any examples or references on where that was documented.
If anyone knows how to center this type of content, I would greatly appreciate your input.
Thank you in advance.
The centering does not work in your jsfiddle because the report gets scaled inside the container and its transform-origin is set to top left. To overcome most of the issues I have come up with the following script based on the one you posted.
The main idea is to add some margins to the ".jrTable" table with the beforeRender event, then to intercept the CSS transform-origin from within visualize.js and set the new one.
Please note that this is not a complete script and does not work on some narrow window setups. I did not run it on a dashboard either.
You will have to decide when to set this new origin based on some measurements. Also, the jQuery's cssHook will probably need adjustments for different vendor prefixes if you intend to target other browsers. I tested it only in Chrome and Safari with the default one. More info on jQuery cssHooks.
EDIT: It seems that the initial solution based on changing the margin and the transform-origin produces unpredictable results and does not scale correctly in all cases. Keeping it for reference here, though.
Better results can be achieve just by adjusting the offset after the transform-origin is applied:
window.addEvent('load', function() {
var hookRegistered = new $.Deferred();
var $container = $("#container");
function adjustPageOffset($jrPage) {
var pageWidth = $jrPage[0].getBoundingClientRect().width,
containerWidth = $container.width();
(pageWidth<containerWidth) ? $jrPage.offset({left:(containerWidth-pageWidth)/2}) : $jrPage.offset({left:0});
}
__visualize__.require(["jquery"], function($) {
$.cssHooks["transformOrigin"] = {
set: function( elem, value ) {
elem.style["transformOrigin"] = value;
if ($(elem).is(".jrPage") && "top left" === value) {
adjustPageOffset($(elem));
}
}
};
hookRegistered.resolve();
});
// wait for the hook to register in visualize's embedded jQuery
// then load the report
hookRegistered.then(function() {
visualize({
auth: {
name: "joeuser",
password: "joeuser",
organization: "organization_1"
}
}, function (v) {
//render dashboard from provided resource
v("#container").report({
resource: "/public/Samples/Reports/06g.ProfitDetailReport",
scale: "container",
error: handleError
});
//show error
function handleError(err) {
alert(err.message);
}
});
});
});
And the modified jsfiddle.

How to center a handsontable properly

I am using handsontable and I would like to show a table centered in the page or a div.
I have managed to do this by changing the width of the container div after the table is initiated (see snippet). However this seems cumbersome.
$(document).ready(function () {
var container = document.getElementById('basic_example');
var hot = new Handsontable(container, {
data: Handsontable.helper.createSpreadsheetData(10, 12),
colHeaders: true,
rowHeaders: true,
afterInit: function () {
$("#basic_example").css("width", $("#basic_example .wtHider").css("width"))
}
});
});
#basic_example {
margin-left: auto;
margin-right: auto;
}
<link href="http://handsontable.com//styles/main.css" rel="stylesheet">
<link href="http://handsontable.com//bower_components/handsontable/dist/handsontable.full.min.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://handsontable.com//bower_components/handsontable/dist/handsontable.full.min.js"></script>
<div id="basic_example"></div>
Is there an easy/better way of centering a handsontable?
Using your work-around, I would recommend using afterRender instead of afterInit in order to update the size of your table whenever the handsontable is rendered.
This would be especially useful if the user changes the size of the screen, if you allow the addition of columns or rows, or if there are other possibilities of the table changing sizes after the original initialization.
Based on the earlier answers, I used the afterRender (and afterChange) events as follows:
afterRender: function () {
let wtHider = document.querySelector('#tableContainer .wtHider');
container.style.width = wtHider.style.width
},
However, when you hide a column, it seems that afterRender is fired too early, before the element with the wtHider class is updated.
Adding a delay of 0 ms solves this issue:
afterRender: function () {
let wtHider = document.querySelector('#tableContainer .wtHider');
setTimeout(() => {
container.style.width = wtHider.style.width
}, 0);
},
Note: Tested using chromium version 87.0.4280.66, Ubuntu 20.04 and handsontable 8.2.0

tooltip width is hidden when mouse over on table header

I have a scenario to show the tooltip on mouse over, it works fine but at table header the tooltip width is hidden.
Below code is causing the issue, but i should not remove that code, please suggest how to enhance the written css code to make tooltip fully displayed. Full working sample with code: http://jsfiddle.net/8WKTj/41/
$(document).ready(function () {
gridviewScroll();
});
function gridviewScroll() {
gridView1 = $('#GridView1').gridviewScroll({
width: 1545,
height: 500,
railcolor: "#F0F0F0",
barcolor: "#CDCDCD",
barhovercolor: "#606060",
freezesize: 3, // no of columns to lock on the left
arrowsize: 30,
headerrowcount: 1,
railsize: 16,
barsize: 8
});
}
PS: If i remove the above mentioned code from my jsp file, tooltip works fine but i should not remove that code.Thanks.
Initialize hover effect before the function call. Please see the JSFIDDLE
$(document).ready(function () {
$("span.question").hover(function () {
$(this).append('<div class="tooltip"><p>Text goes here....</p></div>');
}, function () {
$("div.tooltip").remove();
});
gridviewScroll();
});
Try this if it helps: http://goo.gl/mDN4CR
You can also change the tooltip text via JS

Jquery fade in and fade out effect changes with firefox (JavaScript)

I used Jquery on a table. If I move my mouse over a row it will change color.
The following Javascript was made for IE7, the effect works perfectly here.
When I run this script in Firefox the text fades with the background.
This effect in Firefox shows an empty (white) row on fading out.
Probably he does this because the effect is on the whole row.
Is there a way to keep the text visible at all times?
(the text is in a )
$(document).on({
mouseenter: function(e) {
$(this).fadeIn('fast', function() {
$(this).addClass("white");
});
},
mouseleave: function(e) {
$(this).fadeOut('fast', function() {
$(this).removeClass("white");
});
$(this).fadeIn('fast', function() {
$(this).addClass("grey");
});
}
}, 'table[id*="tbl_main"] tbody tr[id*="dataCell_"]');
Html of a row of the table:
<tr id="ctl00_contentHolder_dataCell_lbl_currencyMisc0" class="grey">
<td align="center"><input type="image" name="ctl00$contentHolder$0-181337" id="ctl00_contentHolder_0-181337" runat="server" src="img/plus.gif" style="border-width:0px;" /></td>
<td title="New Network Hub" align="center">181337</td><td align="center">11337.06</td>
<td align="center"><span id="ctl00_contentHolder_lbl_currencyMisc1">USD</span></td>
<td align="center">6</td><td align="center">31337.36</td><td align="center"><span id="ctl00_contentHolder_lbl_currencyReport1">USD</span></td>
<td align="center">12</td><td align="center">13371.3</td><td align="center">63.82%</td>
You are trying to fadeIn or fadeOut the tr element. Firefox works well if it doesn't show you the content after fadeOut because it should be hided (with CSS -> display:none). That's the mission of fadeOut :) - have a look at the API .
If I understand your question, you want to change the background color with a smooth effect. If yes, then JQuery UI .toggleClass(...) is what you are searching for. The JQuery library has also a toggleClass(...) method, but without any effects. It changes the class immediately.
I created an example on JSFiddle.
I think you should try with this:
var state = true;
$( "#tab tr" ).hover(function() {
if ( state ) {
$(this).stop().animate({
backgroundColor: "#f99"
}, 500 );
} else {
$(this).stop().animate({
backgroundColor: "#fff"
}, 500 );
}
state = !state;
});
});
CHECKOUT THE BIN
For this you need a jQuery ui library if you want to animate colors.

Jquery animate isn't animating

I'm working on a web site that uses the jquery animate function to expand the web site from the top left corner when it is loaded. I wasn't actually the one who wrote the code for that feature so I'm not overly familiar with it. It did work at one point but at the moment it doesn't seem to be working at all. I know the .js file is being loaded and is running because the first bit of code in it is a time delay that shows a "Page is being loaded" message. But then it just shows the page already loaded instead of animating the page appearing from the top left and sliding in. I included the CSS and mark up also although I don't believe that's where the problem lies. Any help would be appreciated! Thanks!
Note: We're using Jquery version 1.7.2
The CSS:
#builder
{
position:relative;
min-height:100%;
min-width:100%;
z-index:999;
}
The JavaScript:
function hideIt() {
document.getElementById("wait").style.display = "none";
}
setTimeout("hideIt()", 1000);
function showIt() {
document.getElementById("builder").style.display = "block";
}
setTimeout("showIt()", 2500);
function build() {
$(document).ready(function () {
$("#builder").animate({ height: '0%', width: '0%' }, 1);
$("#builder").animate({ height: '100%', width: '100%' }, 2000);
});
}
The mark up:
<body onLoad="build()">
<img src="wait.gif" id="wait" style="display:block;" />
wait.gif is just a picture that says "page is loading"...
And the page is wrapped in these:
<div id="builder" align=center style="display:none;">
If the #builder element is hidden for 2.5 seconds before it's shown, the animation will be completed by the time the element is shown. Remove the inline function on body onLoad and try:
function hideIt() {
$("#wait").hide();
}
function showIt() {
$("#builder").show(2000); //should do somewhat the same as animating from the top left
}
$(function() {
setTimeout(hideIt, 1000); //no need to quote the functions and eval them
setTimeout(showIt, 2500);
});
or just
$("#wait").delay(1000).hide(10);
$("#builder").delay(2500).show(2000)
Likely that it's being animated long before your show() is invoked. So by the time it's displayed, the animation is done.
Try adjusting your code like so:
$(document).ready(function() {
$('#wait').hide(1000, function(){ // hide the #wait
$("#builder").show().animate({ // then show, then animate #builder
height: '100%',
width: '100%'
}, 2000);
});
});
Side Note: Remember that when you're using percentages and the element containing #builder, also needs to have it's height and width set.

Categories

Resources