How to center a handsontable properly - javascript

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

Related

How do I make the entire tingle modal containing an image visible on load?

On load and if browser width is greater than 540px, the modal containing an image is cut-off (see figure below). What should I do to make the vertical scroll-bar immediately appear?
This existing project that I'm working on is using tingle modal plug-in. It is linked like so:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="tingle.min.css">
<style>
html, body {
height: 100%;
}
img {
height: auto;
width: 100%;
}
</style>
<title>Tingle Modal</title>
</head>
<body>
<script src="tingle.min.js"></script>
<script src="modal.js"></script>
</body>
</html>
modal.js is where I create the modal containing the image:
function createModal(content) {
let $modal = new tingle.modal({
footer: false,
stickyFooter: false,
closeMethods: ["overlay", "button", "escape"],
closeLabel: "Close",
cssClass: ["modal"],
beforeClose: function() {
return true; // close the modal
},
onClose: function() {
$modal.destroy();
}
});
$modal.setContent(content);
$modal.open();
}
createModal("<div id='modal'><img id='sample' src='sample.jpg' /></div>");
console.log(document.getElementById("sample").offsetHeight);
I noticed that when you zoom-in or zoom-out, or resize the browser, I then get the expected behavior of having the scroll-bar. I also noticed that on load, the image height is 0. I can't set the image height to a pixel value because I'll have several modals containing different images that vary on sizes.
You can also see the behavior here: CodeSandbox. Please do make the embedded browser width in CodeSandbox bigger first, then refresh to see what I mean.
I have tried the following. But it then adds the scroll bar even when the entire modal fits in 100vh, which is not desirable.
.tingle-modal {
overflow-y: scroll;
}
Try adding these styles
.tingle-modal {
overflow-y: auto;
}
If you need to save the position of the close button, then add:
.tingle-modal__close {
position: sticky;
align-self: end;
}
And instead of
createModal("<div id='modal'><img src='sample.jpg' /></div>");
use it
const img = new Image();
img.onload = () => {
createModal("<div id='modal'><img src='sample.jpg' /></div>");
};
img.src = "sample.jpg";
I looked at the code in tingle.min.js. It checks if the height of the modal overflows, if so, it adds a tingle-modal--overflow class. However, the image isn't loaded yet when it checked the height. So I had to redo the checking after calling the createModal function like so:
document.getElementsByTagName("img")[0].onload = function() {
const $modal = document.getElementsByClassName("tingle-modal")[0];
if (window.innerHeight <= $modal.clientHeight)
$modal.classList.add("tingle-modal--overflow");
};
Here's a jQuery version of the solution:
$(".tingle-modal-box img").on("load", function() {
const $modal = $(".tingle-modal");
if (window.innerHeight <= $modal.height())
$modal.addClass("tingle-modal--overflow");
});

Monaco editor dynamically resizable

I have been searching for a discussion about if it's possible to mimic the html tag textarea's resizing when using Monaco Editor's field all over the Internet but I couldn't find one answering my question.
I'm using the monaco-editor npm package in a React application. Do you have any idea if this is easy to implement?
Thank you in advance!
SOLUTION
With pure css I selected the target html element and just added these properties:
div {
resize: vertical;
overflow: auto;
}
TL;DR: add automaticLayout: true to your editor's configuration.
NL;PR:
Monaco has a built-in auto resize to parent container functionality:
createEditorWithAutoResize(){
this.editor = monaco.editor.create(
this.editorDiv.current, {
value: "var x = 0;",
language: 'javascript',
automaticLayout: true // <<== the important part
}
);
}
componentDidMount(){this.createEditorWithAutoResize();}
constructor(props){super(props); this.editorDiv = React.createRef();}
render(){return <div ref={this.editorDiv} className="editor" ></div>}
And the CSS for the editor (it avoids rendering the editor for the first time with like 10px height):
.editor{
height: 100%;
}
First tested: v0.10.1, Last tested: v0.32.1
Note:
< v0.20.0: The mechanism does not listen to its container size changes, it polls them.
#nrayburn-tech (Monaco Editor's contributor): Version 0.20 uses MutationObserver for all browsers. Version 0.21 and later uses ResizeObserver on supported browsers, otherwise, it uses polling as a fallback.
if you have a reference to the editor you can just call
editor.layout()
on some resize event.
For example, on window resize:
window.onresize = function (){
editor.layout();
};
For anyone coming here having this issue in a basic web app (html, css, javascript) I've found a solution for the resizing issue I'm experiencing.
I have the monaco editor in a resizable flex container. It will only grow the width, not shrink it, and vertical resizing doesn't seem to work out of the box.
If you use the monaco config "automaticLayout: true" and the following CSS it seems to resize as expected:
.monaco-editor { position: absolute !important; }
I tried the max-width 99% trick but it causes a laggy delayed effect when increasing the width near edge of page.
For posterity, the solution I arrived on was to set automaticLayout: false so that I could perform all the layout in a resize event listener.
const placeholder = document.getElementById('placeholder')
const editor = monaco.editor.create(placeholder, {
value: '// hello world',
language: 'javascript',
automaticLayout: false // or remove, it defaults to false
})
// we need the parent of the editor
const parent = placeholder.parentElement
window.addEventListener('resize', () => {
// make editor as small as possible
editor.layout({ width: 0, height: 0 })
// wait for next frame to ensure last layout finished
window.requestAnimationFrame(() => {
// get the parent dimensions and re-layout the editor
const rect = parent.getBoundingClientRect()
editor.layout({ width: rect.width, height: rect.height })
})
})
By first reducing the editor layout to 0 we can safely query the dimensions of the parent element without the child (editor) contributing to its size. We can then match the editor to the new parent dimensions. Since this takes place over a single frame, there should be no flickering or lag.
this is old question but get the problem to and solved it with react-resize-detector
based on ResizeObserver it feet perfectly to the need (check browser compatibility)
Exemple of component :
import React, { Component } from 'react';
import ReactResizeDetector from 'react-resize-detector';
import * as monaco from 'monaco-editor';
class Editor extends Component {
constructor(props) {
super(props)
this.state = {
width: 0,
height: 0,
}
this.editor_div = React.createRef()
this.handle_rezise = this.handle_rezise.bind(this);
}
componentDidMount() {
const editor_model = monaco.editor.createModel('', 'sql');
this.monaco_editor = monaco.editor.create(this.editor_div.current, this.props.editorOptions);
this.monaco_editor.setModel(editor_model);
}
componentWillUnmount() {
this.monaco_editor && this.monaco_editor.dispose();
}
handle_rezise(width, height) {
this.monaco_editor.layout({ height, width });
}
render() {
return(
<div
className="editor-container"
style={{ height: '100%' }}>
<ReactResizeDetector
handleWidth
handleHeight
onResize={ this.handle_rezise }
refreshMode="debounce"
refreshRate={100} />
<div
className="editor"
ref={ this.editor_div }
style={{ height: '100%' }} />
</div>
)
}
}
export default Editor;
Hope it's help
In my case I'm using that exact CSS but although automaticLayout: true works, I found out overkill (seems to pooling the DOM 100ms interval and I have several editors opened in the document. SO I ended up implementing it manually :
just in case , my needs are different: I want the user to resize it the container - in a standard way and cheap (both on code and performance) on libraries and performance. This is what I did:
css container : resize: vertical; overflow: auto
and this js :
function installResizeWatcher(el, fn, interval){
let offset = {width: el.offsetWidth, height: el.offsetHeight}
setInterval(()=>{
let newOffset = {width: el.offsetWidth, height: el.offsetHeight}
if(offset.height!=newOffset.height||offset.width!=newOffset.width){
offset = newOffset
fn()
}
}, interval)
}
const typeScriptCodeContainer = document.getElementById('typeScriptCodeContainer')
typeScriptCodeEditor = monaco.editor.create(typeScriptCodeContainer, Object.assign(editorOptions, {value: example.codeValue}))
installResizeWatcher(typeScriptCodeContainer, typeScriptCodeEditor.layout.bind(typeScriptCodeEditor), 2000)
yes, 2 seconds interval and make sure it registers only once. I see there is / was a resize interval on 100ms for the automatic relayout in monaco - IMHO that's too much.
See it in action: https://typescript-api-playground.glitch.me/?example=2

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.

UI-Grid does not take 100% width on page load

I am using ui-grid to showing data in table. when i load the page and leave for few second and then click on the tab (which containing ui-grid), the ui-grid css break. it does not show width of ui-grid 100% of container.but when i load page and just click on tab (containg ui-grid). ui-grid is showing perfect, i mean width of that is 100% of container. I don't know what is the problem.this is the code, i am working on :
Js:
$scope.gridOptions= {
enableFiltering: true,
enableGridMenu : true,
enableRowSelection: true,
enableSelectAll: true,
selectionRowHeaderWidth: 50,
// rowHeight: 35,
// infiniteScrollRowsFromEnd: 50,
// infiniteScrollUp: true,
infiniteScrollDown: true,
columnDefs : [
{ displayName:"Attribute",field: 'attributeId',filter: {placeholder: 'Search Attribute'},width:'10%'},
{ displayName:"Section",field: 'sectionRef.attributeSectionId' ,filter: {placeholder: 'Search Section'}},
{ displayName:"Type",field: 'types',filter: { placeholder: 'Search Types'} }
]
}
Html:
<div class="grid m-b-20" ui-grid="gridOptions" ui-grid-move-columns ui-grid-edit ui-grid-resize-columns ui-grid-pinning ui-grid-selection ui-grid-grouping ui-grid-infinite-scroll>
</div>
Note: ui-grid is inside Angular bootstrap Tab
and here is the snapshot of collapse grid :
Are you using an animation on page load - perhaps a tab or a modal? If so, then the usual workaround is the one we use in the modal tutorial: http://ui-grid.info/docs/#/tutorial/110_grid_in_modal
The problem is that the grid isn't responsive, it gets it's size on render. If you haven't given a fixed size it gets it from the container size. If your container is being animated at the time, the size may not be the real size.
$timeout(function () {
$scope.gridApi.core.handleWindowResize();
}, 500);
$scope.gridApi.core.refresh();
This did the job for me.
use $scope.gridApi.core.handleWindowResize(); this method in interval time to solve this problem
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi;
$scope.mySelectedRows = $scope.gridApi.selection.getSelectedRows();
//$scope.gridApi.grid.registerRowsProcessor($scope.singleFilter);
gridApi.selection.on.rowSelectionChanged($scope, function(row) {
$scope.selectedUser = row.entity.dev_id;
console.log(row);
console.log(row.grid.selection.lastSelectedRow.isSelected);
/*$http.get('./api/ioni_developers/' + $scope.selectedUser).then(function(response) {
if(row.grid.selection.lastSelectedRow.isSelected === true){
$scope.data.dev_id = response.data.dev_id;
$scope.data.dev_name = response.data.dev_name;
$scope.data.dev_email = response.data.dev_email;
$scope.selected = false;
}else{
$scope.data.dev_id = '';
$scope.data.dev_name = '';
$scope.data.dev_email = '';
$scope.selected = true;
}
})*/
});
$scope.selected = true;
$interval( function() {
$scope.gridApi.core.handleWindowResize();
}, 500, 10);
}
The workaround for this is adding the width and rowHeight
for row and cell. As I indicated this is a workaround and I am sure there must other ways of doing this but this a quick fix and should get you what you at least going :)
$scope.gridOptions={
//set the row height to a fixed length
rowHeight: 80,
enableFiltering: true,
enableGridMenu : true,
enableRowSelection: true,
enableSelectAll: true,
selectionRowHeaderWidth: 50,
infiniteScrollDown: true,
columnDefs : [
{ displayName:"Attribute",field: 'attributeId',filter: {placeholder: 'Search Attribute'},width:100},
{ displayName:"Section",field: 'sectionRef.attributeSectionId' ,filter: {placeholder: 'Search Section'}, width:100},
{ displayName:"Type",field: 'types',filter: { placeholder: 'Search Types'} , width:100}
]}
With the suggested polling approach, the function is called after a specified wait, so each width change occurs suddenly. This results in substantial judder when the user quickly changes the table size.
A much better approach is to bind a resize handler to call a resize function when the viewport changes
angular.element($window).bind('resize', () => {
this.updateTableWidth();
});
My project uses a sidebar, so I account for the sidebar width or padding width (if sidebar is open or not), then just set a variable bound to an ng-style on my table wrapper
private updateTableWidth() {
let width = this.$window.innerWidth;
let modifier = (width >= 1280) ? this.sidebarWidth : this.paddingWidth;
this.tableWidth = (width - modifier) + 'px';
}
<div ng-style="{'width': ctrl.tableWidth}">
<div ui-grid></div> <!-- Whatever your grid is -->
</div>
This is what worked for me like a charm!
Add say ng-style="windowResize" to the ui grid markup in HTML template, and on $scope.windowResize, add width: 100% within onRegisterApi function within the scope.
So, basically onRegisterApi() is the default function from ui-grid that triggers when grid is actually drawn, and so basically we are conditionally adding width 100% to grid and making it responsive for all viewports.
Remove ui-grid-resize-columns from your HTML div tags.

jQuery Datatables Header Misaligned With Vertical Scrolling

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;
}

Categories

Resources