How to scroll table's "tbody" independent of "thead"? - javascript

As specified in the W3 specification for Tables:
Table rows may be grouped into a table head, table foot, and one or
more table body sections, using the THEAD, TFOOT and TBODY elements,
respectively. This division enables user agents to support scrolling
of table bodies independently of the table head and foot.
I created the following example, but it doesn't work.
HTML:
<table>
<thead>
<tr>
<td>Problem</td>
<td>Solution</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
JS:
$(function() {
for (var i = 0; i < 20; i++) {
var a = Math.floor(10 * Math.random());
var b = Math.floor(10 * Math.random());
var row = $("<tr>").append($("<td>").html(a + " + " + b + " ="))
.append($("<td>").html(a + b));
$("tbody").append(row);
}
});
CSS:
table {
background-color: #aaa;
}
tbody {
background-color: #ddd;
height: 100px;
overflow: auto;
}
td {
padding: 3px 10px;
}

The missing part is:
thead, tbody {
display: block;
}
Demo

I saw this post about a month ago when I was having similar problems. I needed y-axis scrolling for a table inside of a ui dialog (yes, you heard me right). I was lucky, in that a working solution presented itself fairly quickly. However, it wasn't long before the solution took on a life of its own, but more on that later.
The problem with just setting the top level elements (thead, tfoot, and tbody) to display block, is that browser synchronization of the column sizes between the various components is quickly lost and everything packs to the smallest permissible size. Setting the widths of the columns seems like the best course of action, but without setting the widths of all the internal table components to match the total of these columns, even with a fixed table layout, there is a slight divergence between the headers and body when a scroll bar is present.
The solution for me was to set all the widths, check if a scroll bar was present, and then take the scaled widths the browser had actually decided on, and copy those to the header and footer adjusting the last column width for the size of the scroll bar. Doing this provides some fluidity to the column widths. If changes to the table's width occur, most major browsers will auto-scale the tbody column widths accordingly. All that's left is to set the header and footer column widths from their respective tbody sizes.
$table.find("> thead,> tfoot").find("> tr:first-child")
.each(function(i,e) {
$(e).children().each(function(i,e) {
if (i != column_scaled_widths.length - 1) {
$(e).width(column_scaled_widths[i] - ($(e).outerWidth() - $(e).width()));
} else {
$(e).width(column_scaled_widths[i] - ($(e).outerWidth() - $(e).width()) + $.position.scrollbarWidth());
}
});
});
This fiddle illustrates these notions: http://jsfiddle.net/borgboyone/gbkbhngq/.
Note that a table wrapper or additional tables are not needed for y-axis scrolling alone. (X-axis scrolling does require a wrapping table.) Synchronization between the column sizes for the body and header will still be lost if the minimum pack size for either the header or body columns is encountered. A mechanism for minimum widths should be provided if resizing is an option or small table widths are expected.
The ultimate culmination from this starting point is fully realized here: http://borgboyone.github.io/jquery-ui-table/
A.

try this.
table
{
background-color: #aaa;
}
tbody
{
background-color: #ddd;
height: 100px;
overflow-y: scroll;
position: absolute;
}
td
{
padding: 3px 10px;
color: green;
width: 100px;
}

thead {
position: fixed;
height: 10px; /* This is whatever height you want */
}
tbody {
position: fixed;
margin-top: 10px; /* This has to match the height of thead */
height: 300px; /* This is whatever height you want */
}

mandatory parts:
tbody {
overflow-y: scroll; (could be: 'overflow: scroll' for the two axes)
display: block;
with: xxx (a number or 100%)
}
thead {
display: inline-block;
}

Related

i need to freeze the Top line in the table in html

enter image description here[![enter image description here][2]][2]
I've written an html code for the table which is holding with child id and now I need to freeze the only header and scroll the data if I apply styles it is not matching the lines that divide each column.
See my attached picture when I try to freeze the first line and it is already declared with certain widths but now it is compressing the widths.
Actually it looks like pic2 and if I am trying to do so it is becoming like pic1 can any one suggest me the best solution for this
These not freezing the header because it is declared as single table.
[enter image description here][2]
enter image description here
Try this css:
table {
width: 100%;
}
thead, tbody, tr, td, th {
display: block;
}
tr:after {
content: ' ';
display: block;
visibility: hidden;
clear: both;
}
tbody {
height: 120px; /* Change this with your needs. */
overflow-y: auto;
}
tbody td, thead th {
width: 19.2%; /*If 5 columns then 19.2*/
float: left;
}
https://jsfiddle.net/4aazdqbc/2/

Vertical gaps between inline-block elements for big amounts of elements

I am currently doing the JS/jQuery Project for The Odin Project and i think my solution is performing really well.
The problem i have with it tho, is that for bigger amounts of elements (in JSFiddle it starts to break around 40-45 elements per line, in my Chrome Browser around 50-52), there will be a vertical gap between the elements of two adjacent rows. I initially set vertical-align: top to remove the gaps, which works up to the mentioned 40-50 elements per row.
Here is the JSFiddle.
If you raise the amount of elements per row in the JS file (set it to 50 or higher), you will see what i mean.
This is not the behavior i am looking for. I want a connected grid with no gaps between the cells on either side. Any idea what breaks the vertical-align: top?
Edit: I think it has to do with the percentage-width/height, as it also breaks on numbers below 40, if the result of the division is a "difficult fraction".
Inline boxes inherit inheritable properties from their block parent box. therefore your grids are taking line-height of .container. When .container is overflowed vertical-align: top; stops working, so it's better to use line-height:0; to parent element (.container).
Source: https://www.w3.org/TR/CSS2/visuren.html#inline-boxes
$(document).ready(function() {
createGrid(48);
$(".cell").mouseenter(function() {
$(this).css("background-color", "green");
});
$(".cell").mouseleave(function() {
$(this).css("background-color", "white");
});
});
function createGrid(n) {
var container = $(".container");
container.empty();
var sizeP = 100 / n;
var cell = $('<div/>', {
class: 'cell',
style: 'width: ' + sizeP + '%; height: ' + sizeP + '%;'
});
for(i = 0; i < n*n; i++) {
container.append(cell.clone());
}
}
.container {
border: 5px solid black;
border-radius: 5px;
padding: 10px;
margin: 10px;
width: 800px;
height: 800px;
line-height:0;
}
.cell {
display: inline-block;
box-sizing: border-box;
border: 1px solid black;
vertical-align: top;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<body>
<div class="container"></div>
</body>

How to remove/change print document margin in printTask?

I wonder how I can achieve a borderless print.
At the moment my output looks like this:
I'd like to have the image start at the very top left corner. Is this possible? I already tried to set a negative margin to my print-style box, but the image will get cut then.
I know that maybe not all printers are capable of printing the area of the border, but in my use-case the picture will be white in these areas. (The mountain-image is just for demo purposes)
Can I specify the document border somehow via printTask?
See my current setup:
HTML:
<div id="pdf-render-output"></div>
CSS:
body > #pdf-render-output {
display: none;
}
#media print {
body > * {
display:none;
max-width: 100%;
}
html {
max-width: 100%;
border-top: 0;
}
body > #pdf-render-output {
display: block;
border: none;
max-width: 100%;
width: 100%;
height: 100%;
position: relative;
margin: 0; /* I tried to set negative margin/padding eg. here */
padding: 0;
}
}
JS:
$('#pdf-render-output').append("<img src="..." style=\"width: 100%\" />");
I played around with all possible margins/paddings and stuff, but the image will get cut and the white border stays 'over' it.
I hope that there might be a printTask-option I missed browsing the msdn?
Update:
I tried to set all margin/padding/border values with !important. No change.
Here is a screenshot from the simulator, displaying only the print-css-style:
I got to the point thinking it's an issue with the printTask itself. Are there any options regarding to this problem?
If the margin values of DocumentSource is set to 0, gaps will decrease very much. However, compared with PrintTask by C#+XAML, a top margin(Probably header/footer area) is made a little.
var printTask = printEvent.request.createPrintTask("Print Sample", function (args) {
var src = MSApp.getHtmlPrintDocumentSource(document);
src.rightMargin = 0;
src.leftMargin = 0;
src.topMargin = 0;
src.bottomMargin = 0;
src.shrinkToFit = false;
args.setSource(src);
}
In my environment, when this CSS was used, it has removed the margin without the necessity for src.rightMargin, etc.
#page {
margin:0cm;
}

How to replace a table cell with another cell while preserving the table size

Consider the following jsFiddle - http://jsfiddle.net/mark69_fnd/rcCeG/17/
Although it utilizes YUI, the code should be pretty clear:
YUI().use('node', function (Y){
var td = Y.one('#replaceMe'),
newTd = Y.Node.create('<td><input/></td>'),
w = td.getDOMNode().getBoundingClientRect().width,
inputNode = newTd.one('input');
w -= parseFloat(td.getComputedStyle('paddingLeft')) || 0;
w -= parseFloat(td.getComputedStyle('paddingRight')) || 0;
w -= 2 * parseFloat(td.getComputedStyle('borderWidth')) || 0;
newTd.setStyle('width', w + 'px');
w -= 2 * parseFloat(inputNode.getComputedStyle('borderWidth')) || 0;
inputNode.setStyle('width', w + 'px');
td.replace(newTd);
});​
What it does is replaces a cell in the given table with another cell, containing an input box.
Now, I had to perform some width calculations in order for the replacement to preserve the table size. What bothers me especially, is that I had to set the width of the input explicitly, even though it is set to 100% in the CSS:
table, td, th {
border: solid 1px black;
}
table td, table th {
padding: 2px;
}
input {
border: 1px solid #cbcbcb;
background-color: #FFFEBB;
width: 100%;
height: 100%;
}
If I do not set it, then it looks ugly - the right padding is not respected and I do not understand why.
Please, show me the right way to replace one cell with another while preserving the table size.
The thing is that the table-cell's width comes from it's children's width. 100% of a width that adjusts to the the width of it's children well... If the input, being a child of td, determines the td's width, what will the 100% do? It won't do nothing... It'll keep the input at it's default size.
Basically, percentage width values inside elements that adjust to it's inner content will be relative to their natural sizes. And another thing: the parent's width will always be equal to the the same natural size of the inner content.
You can see this behavior with floats, as well: jsfiddle.net/joplomacedo/gBvn4/
I hope I've made myself clear. I'm in a hurry right now, and can't take the time to clean or better structure the answer.
Why don't you just explicitly set the width and height of all the cells at once?:
table th, table td {
width: 25px;
height: 25px;
}
http://jsfiddle.net/pitaj/rcCeG/13/
try to add display: block;
input {
border: 1px solid #cbcbcb;
background-color: #FFFEBB;
display: block;
width: 100%;
height: 100%;
}
you will need to play with paddings or floating maybe, but generally it should work.

stop table cell from expanding, or set input to width of table cell

I have been playing around with this and cannot seem to get it functioning as I would like.
here is my example,
I have a table who's cells i'm making editable by replacing their text content with inputs when the user clicks on them. The input is removed after the focus is lost and the cell contents (the input) are replaced by the updated text.
This all works, fabulous. My issue is the cells resize themselves after the text is replaced by the input.
I have set the width of the input to 100%, but that is all I can think of (aside from measuring the cell width and hard-coding it to that width, however I would like to avoid this if possible.)
(see example for html content)
css assume table has ID of #tblListings
#tblListings {
width: 100%;
}
#tblListings thead {
background-color: #dedede;
}
#tblListings td, #tblListings th {
padding: 6px;
border: 1px solid #adadad;
border-bottom: none;
}
#tblListings tbody tr:nth-child(even) td {
background-color: #efefef;
}
#tblListings tbody tr:last-child td {
border-bottom: 1px solid #adadad;
}
#tblListings td input {
width: 100%;
border: none;
outline: none;
background-color: #ff0;
}
javascript I would presume this can be achieved with CSS, however I will post this to be safe.
$("#tblListings tbody").on("click", "td", function(event) {
if (event.target.tagName === "INPUT") return;
var cell = $(this);
var input = $("<input>", {
type: "text",
value: cell.text(),
maxlength: 128
});
cell.empty().css("padding", 0).append(input);
input.focus();
input.on("blur", function() {
cell.css("padding", 6).text(this.value);
});
});
One way to do it would be to set the input to have absolute positioning but keep the original contents in the cell to keep the width the same. See the update here: http://jsfiddle.net/V6rsC/29/.
What I did was set the cell to have relative positioning so that when I set the bounds of the input, it would use the cell instead of the document. I set left, top, right, and bottom of the input to 0px. The width remains the same because the contents are still there, but we cannot see them because the input is in the way. When we are done, the contents are replaced anyway, so know one ever knows the difference.

Categories

Resources