jquery get real table height when tbody has lot of elements - javascript

I have a <table> element with a lot of rows and a max-height attribute.
I need to find the real height displayed for the <tbody> element. Normally I can just take the difference between <table> height and <thead> height
var tbodyDispalyHeight = $("table").height() - $("thead").height();
This works unless horizontal content is too much and an horizontal scrollbar appears (and can't remove it because... I need it!). I should remove its height from tbodyDispalyHeight but... how can I do?
First problem: I don't really know when this bar is displayed
Second prolbem: Each browser implement scrollbar in a different way
Here is a JSBIN example to understand what I mean. Try to resize page horizontally until the scrollbar appears, there the dislayed tbody height should be lower...

Sounds like you are looking for the clientHeight.
(But this seems to be to easy.)
Have a look to MDN
The Element.clientHeight read-only property is zero for elements with no CSS or inline layout boxes, otherwise it's the inner height of an element in pixels, including padding but not the horizontal scrollbar height, border, or margin.
You may try:
$("table")[0].clientHeight

Currently you have your table with overflow:auto. But you could wrap it with a DIV with "overflow:auto". Then you can simply determine if you have a horizontal scrollbar by comparing the width of your div with the width of your table.

Related

Long table scroll, but prevent window scroll

I have a table whith many divs above it:
<div></div>...<div></div>
<div id="tablecontent">
<table>...</table>
</div>
I want my table scroll only in screen (the bottom of table is in the bottom of windows). So I need to set height and scroll=auto for #tablecontent.
To set heigth I calculate it as:
var pos=$("#tablecontent").position().top;
var heigth=$( window ).height()-pos;
$("#tablecontent").css("height",heigth+'px');
But this is not working correctly. It is larger than I need. Can you help me calculating the right value.
On the div in your CSS you'll want to set overflow: scroll, that with the fixed height should create a scroll bar on your div when the contents are larger than the container.

Can I expand a div so the overflow-y:auto scrollbar doesn't clip the div content?

Similar question, without a great answer:
How can I include the width of "overflow: auto;" scrollbars in a dynamically sized absolute div?
I have a <div> of fixed height that acts as a menu of buttons of uniform width. Users can add/remove buttons from the menu. When there are more buttons than can fit vertically in the <div>, I want it to become scrollable - so I'm using overflow-y:auto, which indeed adds a scrollbar when the content is too large in y. Unfortunately, when the scrollbar shows up it overlaps the menu buttons, and adds a horizontal scroll bar as a result - the big problem is it just looks horrible.
Is there a "right" way to fix this? I'd love to learn some style trick to make it work right (i.e. the scrollbar sits outside the div rather than inside, or the div automatically expands to accommodate the scroll bar when necessary). If javascript is necessary, that's fine - I'm already using jQuery - in that case, what are the right events are to detect the scrollbar being added/removed, and how do I make sure to use the correct width in a cross-browser/cross-style way?
JSFiddle: http://jsfiddle.net/vAsdJ/
HTML:
<button type="button" id="add">Add a button!</button>
<div id="menu">
</div>
CSS:
#menu{
background:grey;
height:150px;
overflow-y:auto;
float:left;
}
Script:
$('#add').button().click(function(){
var d = $('<div/>');
var b = $('<button type="button">Test</button>');
d.appendTo($('#menu'));
b.button().appendTo(d);
});
First: To remove the horizontal scrollbar set overflow-x: hidden; as Trent Stewart has already mentioned in another answer.
CSS Approach:
One thing I have done in the past is to add a wider wrapping div around the content div to make room for the scrollbar. This, however, only works if your container width is fixed... and may need to be adjusted (by serving different styles) in various browsers due to variable rendering of scrollbars.
Here a jsfiddle for your case. Note the new wrapper <div id="menu-wrap"> and its fixed width width: 95px;. In this case the wrapper div is doing the scrolling.
You could probably also solve this by giving the wrapper some padding on the right, and thereby avoid the fixed width problem.
jQuery Approach:
Another option is to detect the overflow using jquery as described here, and then increasing the width or padding of the div to make space. You may still have to make browser-specific adjustments though.
Here a jsfiddle with a simplified version for your example. This uses your click function to check the div height after every click, and then adds some padding to make room for the scrollbar; a basic comparison between innerHeight and scrollHeight:
if($('#menu').innerHeight() < $('#menu')[0].scrollHeight){
$('#menu').css( "padding", "0 15px 0 0" );
}
To make this more cross-browser friendly you could check for the scrollbar width (as outlined here) and then add the returned value instead of the fixed padding. Here another jsfiddle to demonstrate.
There are probably many other methods, but this is how I would go about it.
Have you tried simply using overflow-x: visible; or hidden

Position an element at the bottom of a floating div with unknown height

I am currently trying to position an element in a way that it always is at the bottom of it's parent. What's special here is that none of the heights or widths are known. I'd like to do this without tables, if at all possible (my superior is against using those. In a very religious way).
I tried the approach of using position:relative on the parent and position:absolute; bottom:0; on the box I want to have at the bottom. This, however, causes the box to overlap with the other content of the parent div since absolute positioning causes the parent to ignore the height of the positioned element. Some JavaScript is used to align the heights of the floating divs to each other. But disabled JavaScript should not completely break the layout (as in: cause content to overlap or break the "flow" of the page).
Here's the fiddle with the exact structure of my markup: http://jsfiddle.net/vbeC2/27/
I did read the "float: bottom" question on SO, but none of the answers really adressed my problem, hence the new question.
It's not the cleanest solution, but since you were already using the maxHeight bit to calculate the sizes, I just added a second each loop to check the max-height of the bottom section, and added it, so that the relative, absolute positioning would work.
http://jsfiddle.net/robsterlini/svcGB/ or http://codepen.io/robsterlini/pen/BcDyt
EDIT When you resize your browser it won't work, but you could just add a resize event that recalculated it, and you'd need to think about creating some javascript-less fallbacks, either using modernizr, or just some simple
Please find the working demo here: JS Enabled
Modified the jquery logic to calculate the height of the maximum height of the container as shown below:
$(document).ready(function(){
//Set the height of the columns to the highest value of all columns
var maxHeight = 0;
$(".same-height").each(function(){
var k = $(this).children('.headline').innerHeight() + $(this).children('.description').innerHeight()+$(this).children('.bottom').innerHeight();
maxHeight = Math.max(maxHeight,k);
});
$(".same-height").css({"height" : maxHeight});
});
If JavaScript is disabled then you should apply different styles as shown in demo here:
JS Disabled
Here is something similar to what you want to atchive but the demo is centering the
http://css-tricks.com/centering-in-the-unknown/
You should use the same trick : using css ::after/::before pseudo classes to set your footer content in your parent div

width of dynamically inserted div containing text

I have a script that dynamically inserts a div containing text in the dom. The text content is not known in advance.
I need to know the width of this div, but it seems that that the return value of document.defaultView.getComputedStyle(node, "").getPropertyValue("width") or node.offsetWidth cannot be trusted.
I used setInterval to log it, and the value changes over time. For instance, in my case it starts with 929px and then changes to 908px.
This div is in position absolute, it has whitespace nowrap, so I don't think it is being "pushed" by other dom elements or that it somehow changes once inserted.
Is there an elegant way to retrieve the width, or do I have to use an ugly setTimeout to retrieve it once the return value is stable ?
Try:
yourDOMElement.getClientBoundingRect()
This will return an object with top, left, right, bottom, height and width attributes. This should be cross-browser.
Note: If you are going to work with the position attributes (top, left, right, bottom, height) of the returned, take into account scroll offset if necessary.
Update: To ensure this works on older browsers that don't have the width/height attribute, calculate it subtracting right/bottom from left/top.
The viewport can change its size because of the scrollbar. Once the scrollbar appears, its width can no longer be used by the document. Force the scrollbar to exist before you measure the size by adding overflow: scroll or overflow-y:scroll to the <html> element.
The size of a block-level element is, by default, its container width minus margins and padding (even if it's positioned absolutely), which is ultimately the wiewport width unless you set a fixed width somewhere along the way.
Using jQuery, you should be able to do this:
var width = $("div-selector").width();
this is fairly easy?
open the page in a browser and press f12. With firefox there is a button "inspect element" on top and in chrome it's on the bottom. Click it and hover your mouse over it. This should give you the height and width in px. Never been wrong for me.
if it still doesn't show, click it and you can see it in the css panel of the console.

If container width, padding and line-height is known, how to calculate height?

I am adding element dynamically to DOM.
$('<div class="entry"></div>').text(data.status).appendTo(app.twitter_feed);
I want to get element height before it is added to DOM. The usual approach is to add the element within a hidden element with the same style and then simply see what is the height.
Though, is it imposible to calculate element height if you know container's width, padding and line-height (content is only plain-text) and content?
How the content wraps inside a container may depend on browser and zoom level, so unless you're very sure the content will never wrap, I would advise determining the height the way you have described.
If your text font is mono-sized-font, yes you can calculate it with formula [(text-length/(width/char-width))], but I'm sure you are not using mono-sized-font like courier, monospace etc.
Answer is this : there is no way to do this with multi-sized-fonts, me sorry.

Categories

Resources