I have a table where I need fixed td sizes and as such I have the appropriate table-layout: fixed, white-space: nowrap, overflow:hidden, etc etc on the table and td's. It was working great until I had to dynamically resize it by basically adding a row at runtime
Basically I use javascript to add a row
<tr>
<td style="max-width:50px; min-width:50px; width:50px"> </td>
<td style="max-width:50px; min-width:50px; width:50px"> </td>
<td style="max-width:50px; min-width:50px; width:50px"> </td>
</tr>
It didn't work because some of the table td's are overflowing now. Well it turns out the td's even after this row somehow inherit asmax-width: none. When I manually add max-width:50px to an offending overflow td in firebug, the layout gets fixed.
Why is it ignoring the rules I set on the first tr and how can I set all td's to obey?
edit:
here is the fix width code as requested (there are two tables in the tableDiv):
fixWidths : function(tableDiv)
{
var headerTable = tableDiv.find('.headertable');
var widths = [];
headerTable.find("th").each(function(){
widths.push($(this).width());
});
var tr = tableDiv.find('.fixwidth');
for (var i = 0; i < widths.length; ++i)
{
var td = $(document.createElement('th'));
td.css('width', widths[i]);
td.css('min-width', widths[i]);
td.css('max-width', widths[i]);
td.html(' ');
tr.append(td);
}
/* */
}
Related
I am creating a table in plain JavaScript, and filling it up using onClick listener event in two ways - either clicking on a external button, or clicking on one of the cells itself; and in both ways, calling a function to randomly assign values to some of the cells. I am not able to hide the contents of my table cells using either of the methods available- display: none, and visibility: hidden. But I am still able to do it using fontSize = 0., wherin another problem crops-up viz the cells borders are lost. Thus my problem is that I want to hide my table cells contents whilst rendering values in them withput affecting the table structure.
I have already tried conventional methods available viz.
1) td {display: none;}, and td {visibilty: hidden}
2) I have also tried inline CSS style method to hide the cell contents, but all these methods blank the table itself i.e. oblivate the cell borders themselves.
3) When I use:
document.getElementById('myelement').getElementsByTagName('td')[n[i]].style.fontSize = 0; I am able to hide the contents, but then cell borders are lost.
<body>
<div class="container-fluid">
<table id="myelement">
<tr>
<td> </td>
... .... ...
<td> </td>
</tr>
</table>
</div>
</body>
<script>
...
for(let i=0;i<mycount;i++){
td[n[i]].firstChild.nodeValue='X';
document.getElementById('myelement').getElementsByTagName('td')
[n[i]].style.fontSize = 0;
}
...
</script>
All the techniques available blank the table itself i.e. oblivate the cell borders themselves. The expected result is intact table structure when hiding the cells contents.
Something like this?
Cell with class="hidden" will appear to be empty but you can change background: #fff; to any other color you want
td.hidden {
position: relative;
}
td.hidden:after {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #fff;
z-index: 10;
}
<table border=1>
<tr>
<td class="hidden">asd</td>
<td>zxc</td>
<td>test</td>
</tr>
<tr>
<td>asd</td>
<td class="hidden">zxc</td>
<td>test</td>
</tr>
<tr>
<td>asd</td>
<td>zxc</td>
<td class="hidden">test</td>
</tr>
</table>
I have to generate a dynamic table where the user will specify the number of rows and cols and spacing between them and margin. The interface also has a preview pane. The preview will display the user about the currently set options indicating rows cols spacing margin.
I have designed a dynamic table but I am unable to maintain the size of the table as fixed. Since the preview pane is fixed.
How do I maintain a fixed size preview pane where the user can see the upcoming changes before generating table
Say when the user selects rows as 4 and cols as 2 and margin as 0 and spacing as 10 it should display the preview proportionately to the specified size
I have tried with
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<style>
table{width:300px;height:10px;}
td{
width:100px;
height:10px;
overflow:hidden;
word-wrap:break-word;
background-color: #f0f0f0
}
</style>
</head>
<body>
<script>
var rows = 4;
var cols = 5;
var table = $('<table border=1 cellspacing="10" cellpadding="10"><tbody>');
for(var r = 0; r < rows; r++)
{
var tr = $('<tr>');
for (var c = 0; c < cols; c++)
$('<td> </td>').appendTo(tr);
tr.appendTo(table);
}
table.appendTo('body');
</script>
</body>
</html>
Just remove the width property of you td. The table element has it's fixed width, so if you don't specify a width to the td, it will be divided equally between all the cells.
You can set width and height programmatically rather than in style. That would allow you to calculate the required width and height given the user's input.
var table = $(`<table border=1 cellspacing="10" cellpadding="10" style='width: ${width}px; height: ${height}px;'><tbody>`);
You could also just not set width and height of .table and it would just be the size of the contents...
You can do this very simple through Bootstrap. It will handle everything.
You can add a bootstrap styles to your page.
You can add class as
<table class="table">
and you can specify the height and width in % so it will be responsive as per your need.
<table class="table" style="width:90%; height:90%">
Even If you add any number of rows and columns the table will remain same responsive as per your view.
p {
width: 40px;
margin: 0;
padding: 0;
}
td {
padding: 0;
margin: 0;
}
<table style="width:100px;">
<colgroup>
<col style="width:20px;">
<col style="width:40px;">
<col style="width:40px;">
</colgroup>
<tr>
<th>ID</th>
<th>NAME</th>
<th>Email</th>
</tr>
<tbody>
<tr>
<td>1</td>
<td>john</td>
<td>
<p>johntheman#example.com dsdsdsdsdsd dsdsdsdddddddddddddddddddddddsd dsdsssssssssssssdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsdsds
sadddddddddddddddddddddddddd
</p>
</td>
</tr>
</tbody>
</table>
I have simple table with fix width. I also have fix width for columns in it to do that I have used CSS colgroup.
Problem 1:
Width of my columns if I check in developer's tool is different than that of what I have given in colgroup.
What I have tried
While fixing it I have found that the width changes with the text in it if I increase the text td increases and vice versa.
Problem 2:
When I enter the text in td unless I don't break it on new line by hitting enter the width of td goes on increasing with text.
What I have tried
To tackle this problem I have wrap my text in a p tag with fix width and then put it in td but still no luck. What I see is width is getting applied to P tag but text is overflowing.
What I expect :
I would like to know that why text is not breaking itself on new line after the fixed width of td. Why text overflows out of P even after fix width? Why td has to increase even after fix width?
I don't know what I am missing to apply here.
for the table use css property
table-layout: fixed;
Then provide fixed with to your td columns.
The width of the <p> tag and <td> are fixed they are not increasing.
Until there is no space in your text content it will not wrap to next line. You have to use ellipsis which will put ... in place of overflowing text content. Use below css for your <p> tag.
p {
width: 40px;
margin: 0;
padding: 0;
text-overflow: ellipsis;
overflow: hidden;
}
I have a dynamic table in my web page that sometimes contains lots of rows. I know there are page-break-before and page-break-after CSS properties.
Where do I put them in my code in order to force page breaking if needed?
You can use the following:
<style type="text/css">
table { page-break-inside:auto }
tr { page-break-inside:avoid; page-break-after:auto }
</style>
Refer the W3C's CSS Print Profile specification for details.
And also refer the Salesforce developer forums.
Wherever you want to apply a break, either a table or tr, you needs to give a class for ex. page-break with CSS as mentioned below:
/* class works for table row */
table tr.page-break{
page-break-after:always
}
<tr class="page-break">
/* class works for table */
table.page-break{
page-break-after:always
}
<table class="page-break">
and it will work as you required
Alternatively, you can also have div structure for same:
CSS:
#media all {
.page-break { display: none; }
}
#media print {
.page-break { display: block; page-break-before: always; }
}
Div:
<div class="page-break"></div>
I have looked around for a fix for this. I have a jquery mobile site that has a final print page and it combines dozens of pages. I tried all the fixes above but the only thing I could get to work is this:
<div style="clear:both!important;"/></div>
<div style="page-break-after:always"></div>
<div style="clear:both!important;"/> </div>
Unfortunately the examples above didn't work for me in Chrome.
I came up with the below solution where you can specify the max height in PXs of each page. This will then splits the table into separate tables when the rows equal that height.
$(document).ready(function(){
var MaxHeight = 200;
var RunningHeight = 0;
var PageNo = 1;
$('table.splitForPrint>tbody>tr').each(function () {
if (RunningHeight + $(this).height() > MaxHeight) {
RunningHeight = 0;
PageNo += 1;
}
RunningHeight += $(this).height();
$(this).attr("data-page-no", PageNo);
});
for(i = 1; i <= PageNo; i++){
$('table.splitForPrint').parent().append("<div class='tablePage'><hr /><table id='Table" + i + "'><tbody></tbody></table><hr /></div>");
var rows = $('table tr[data-page-no="' + i + '"]');
$('#Table' + i).find("tbody").append(rows);
}
$('table.splitForPrint').remove();
});
You will also need the below in your stylesheet
div.tablePage {
page-break-inside:avoid; page-break-after:always;
}
this is working for me:
<td>
<div class="avoid">
Cell content.
</div>
</td>
...
<style type="text/css">
.avoid {
page-break-inside: avoid !important;
margin: 4px 0 4px 0; /* to keep the page break from cutting too close to the text in the div */
}
</style>
From this thread: avoid page break inside row of table
When converting to PDF with SelectPdf I couldn't get a group of rows to stay together. Tried to put them in a <div style="break-inside: avoid;"> but that didn't work.
Nothing was working until I found this: https://stackoverflow.com/a/27209406/11747650
Which made me rethink my logic and place the things I didn't want to split inside a <tbody>.
<table>
<thead style="display: table-header-group;">
<tr>
<th></th>
</tr>
</thead>
-- Repeating content --
<tbody style="break-inside: avoid;">
-- First row from group --
<tr>
<td> Only shown once per group </td>
</tr>
-- Repeating rows --
<tr>
<td> Shown multiple times per group </td>
</tr>
</tbody>
This results in a table that has multiple <tbody> but that's something that is completely fine as many people use this exact pattern to group together rows.
If you know about how many you want on a page, you could always do this. It will start a new page after every 20th item.
.row-item:nth-child(20n) {
page-break-after: always;
page-break-inside: avoid;
}
I eventually realised that my bulk content that was overflowing the table and not breaking properly simply didn't even need to be inside a table.
While it's not a technical solution, it solved my problem to simply end the table when I no longer needed a table; then started a new one for the footer.
Hope it helps someone... good luck!
Here is an example:
Via css:
<style>
.my-table {
page-break-before: always;
page-break-after: always;
}
.my-table tr {
page-break-inside: avoid;
}
</style>
or directly on the element:
<table style="page-break-before: always; page-break-after: always;">
<tr style="page-break-inside: avoid;">
..
</tr>
</table>
We tried loads of different solutions mentioned here and elsewhere and nothing worked for us. However we eventually found a solution that worked for us and for us it seems to somehow be an Angular issue. I don't understand why this works, but for us it does and we didn't need any page break css in the end.
#media print {
ng-component {
float: left;
}
}
So just hoping this helps someone else as it took us days to fix.
You should use
<tbody>
<tr>
first page content here
</tr>
<tr>
..
</tr>
</tbody>
<tbody>
next page content...
</tbody>
And CSS:
tbody { display: block; page-break-before: avoid; }
tbody { display: block; page-break-after: always; }
I tried to change the color of the first td element in each row to red.
HTML:
<table id="test">
<tr>
<td>test1</td>
<td>test2</td>
</tr>
<tr>
<td>test3</td>
<td>test4</td>
</tr>
</table>
I tried this JS:
var tr = document.getElementsByTagName('tr');
tr.firstChild.style.color = 'red';
No Jquery please.
Use rows and cells to access the rows and columns of the table. See below code,
var table = document.getElementById('test');
for (var i = 0; i < table.rows.length; i++) {
var firstCol = table.rows[i].cells[0]; //first column
firstCol.style.color = 'red'; // or anything you want to do with first col
}
DEMO: http://jsfiddle.net/QNEyx/
Parsing with JS could be costly, if you are fine achieving the same with the CSS, then here you go.
#test tr td:nth-of-type(1) {
color: red;
}
Or
#test tr td:first-child {
color: red;
}
As said in another reply, css is the natural way to accomplish this.
As you are stuck with js, you can use js to inject a stylesheet in your page:
var styleNode=document.createElement("style");
document.head.appendChild(styleNode);
var cssString="#test tr td:first-child {color: red;}";
if (styleNode.styleSheet) { // IE
styleNode.styleSheet.cssText = cssString;
}
else {
styleNode.appendChild(document.createTextNode(cssString));
}
The benefit of using a stylesheet is that you avoid race conditions (case when the table is built dynamically).