I am pulling back a large amount of tabular data that I wish to display using a table. The only caveat is that I would like to be able to "lock" a few of the columns (fname/lname/email) so that when users scroll horizontally those columns always stay "locked" in place and are visible. I have done something similar to this before but that was back in the frameset days so that approach is no longer valid.
I was thinking about doing something clever with laying tables on top of each other but so far I have had no success with making this work. Anyone have any clever suggestions?
A perfect example of what I am trying to do is here:
http://www.google.com/squared/search?q=world+leaders
If I understood correctly what you want, you can have a container div with position: relative, overflow: auto and fixed width. Inside of it, you separate the part you want to be locked, from the other one, into say, two different divs. The div containing the "locked" part should have position: absolute and left: 0.
It's just the big picture but you should be able to accomplish what you want this way.
The code below should be pretty self-explanatory. You can add/remove rows from TBODY while THEAD remains perfectly static. This is what TBODY and THEAD exist for ;)
<style type="text/css" media="screen">
.myTable
{
border:1px solid #000;
border-spacing:0px;
width:300px
}
.myTable thead td
{
background-color:#000;
color:#FFF;
}
.myTable tbody
{
height:300px;
overflow-y:auto;
overflow-x:hidden;
}
</style>
<table class="myTable">
<thead>
<tr>
<td>Fname</td>
<td>Lname</td>
</tr>
</thead>
<tbody>
<tr>
<td>Lior</td>
<td>Cohen</td>
</tr>
<tr>
<td>Lior</td>
<td>Cohen</td>
</tr>
<!-- put more rows here -->
</tbody>
</table>
Something like this should work:
You are going to have to play with it a little so that you don't have the horizontal scroll bar as well, but you get the idea.
Of course, this didn't work in IE7. It may work in 8, but as always YMMV. Good luck. I hope this gets you started in the right direction.
<html>
<head>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var body = $('#table-body');
for (var i = 0; i < 100; i++) {
var row = $('<tr />');
var fname = $('<td />')
.text('FirstName' + i);
var lname = $('<td />')
.text('LastName' + i);
var email = $('<td />')
.text('FirstLast' + i + '#example.com');
row
.append(fname)
.append(lname)
.append(email);
body.append(row)
}
});
</script>
<style type="text/css">
#table-body {
height: 150px;
overflow: auto;
}
</style>
</head>
<body>
<table>
<thead>
<td>First Name</td>
<td>Last Name</td>
<td>Email</td>
<thead>
<tbody id="table-body">
</tbody>
</table>
</body>
</html>
Related
I have a simple table and I write some JS code in order to achieve that whole tr become a data-href. Everything works very nice except for one thing.
Now the whole row is clickable and that is fine, but there is a small issue, if you click on the delete button, it takes you to the update page (data-href), and I want to avoid that. So my question is how can I modify that code for the whole row to stay clickable except that delete button?
Here is my code:
$("tr").each(function() {
const $tr = $(this);
$tr.attr("data-href", $tr.find("a").attr("href"))
})
$('*[data-href]').on('click', function() {
window.location = $(this).data("href");
});
.modal {
padding:5px;
background-color:red;
color:#fff;
cursor: pointer
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<table>
<tr>
<td>Name</td>
<td> Age</td>
<td>
Update
<a data-toggle="modal" class="modal" data-target="#deleteModal">Delete</a>
</td>
</tr>
</table>
Can somebody try to help me with this?
To achieve this you can use the is() method to determine what element within the tr was clicked on. If it was an a element then you can prevent the window.location from being updated.
Also note that you can update the data-href of each tr using an implicit loop which makes the code slightly more succinct. Try this:
$('tr').attr('data-href', function() {
return $(this).find('a').attr('href');
});
$('*[data-href]').on('click', function(e) {
if (!$(e.target).is('a')) {
window.location.assign($(this).data("href"));
}
});
.modal {
padding: 5px;
background-color: red;
color: #fff;
cursor: pointer
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<table>
<tr>
<td>Name</td>
<td>Age</td>
<td>
Update
<a data-toggle="modal" class="modal" data-target="#deleteModal">Delete</a>
</td>
</tr>
</table>
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>
Below is my html code.Want to change column background color if we get
green color value in that column. so want green background of that
column
means we want change column background color according to color name.
data will be display through web service.
Writing below html code for displaying data in html table
<html>
<head>
</head>
<body>
<table>
<tr>
<th>Risk Category</th>
</tr>
<tr>
<td colspan="1"></td>
</tr>
</table>
</body>
</html>
Use the style inline attribute on td like below.
<td style="background-color:COLOR_NAME_OR_HASH_FROM_SERVER"></td>
Since you may be returning colors that don't necessarily have an interpret-able color (Amber), you may need to write some simple CSS. I just plopped it in the <head> for you, but you can move it to an external CSS file, especially if there's more than a few colors.
But if you can edit the markup, just add the color given by the server as a class on that cell.
<html>
<head>
<style>
.Amber { background: #ffbf00; }
.Green { background: #008000; }
.Red { background: #f00; }
</style>
</head>
<body>
<table>
<tr>
<th>Risk Category</th>
</tr>
<tr>
<td class="Amber" colspan="1">Amber</td>
</tr>
</table>
</body>
</html>
If you can't edit the markup for some reason, you'll need to loop through the table cells with JavaScript and add classes that way. Something like this should get you started:
var cells = document.querySelectorAll('td');
for( i = 0; i < cells.length; i++ ){
text = cells[i].innerText || cells[i].textContent;
cells[i].className = text;
}
And to combine it all, here's a snippet showing how it works adding the classes with JS based on the word pulled from the server.
var cells = document.querySelectorAll('td');
for( i = 0; i < cells.length; i++ ){
text = cells[i].innerText || cells[i].textContent;
cells[i].className = text;
}
.Amber { background: #ffbf00; }
.Green { background: #008000; }
.Red { background: #f00; }
<html>
<head>
</head>
<body>
<table>
<tr>
<th>Risk Category</th>
</tr>
<tr>
<td colspan="1">Amber</td>
</tr>
<tr>
<td colspan="1">Green</td>
</tr>
<tr>
<td colspan="1">Red</td>
</tr>
</table>
</body>
</html>
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; }
This question already has answers here:
Set element width or height in Standards Mode
(2 answers)
Closed 8 years ago.
I used this code to get the height of a dynamic table
var table = document.getElementById("test");
document.write(table.offsetHeight);
But now I need to use that value to set the height of a div beside that table. I don't know how to do this. I was hoping it could be done easily through the inline style of the div but I couldn't do it.
Thanks
Since you already know how to get the table's offsetHeight, you can set it to the div by the DOM style property:
var table = document.getElementById("test");
document.getElementById("myDiv").style.height = table.offsetHeight + "px";
you can do
var height=$('table').height() to get the height.
For specific div
$('div').height(height)
rather than writing table you can specify its id also. Same with div. You can specify the id of div to change the height of particular div
Here is an example of how to do this using jquery when the page loads:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<table id="table" style="width: 200px; border: 1px solid black; float: left;">
<tr>
<td>test</td>
<td>tttttttttttttttttttttttttttttttttttttttttttttttttttttt</td>
</tr>
<tr>
<td>test</td>
<td>tttttttttttttttttttttttttttttttttttttttttttttttttttttt</td>
</tr>
<tr>
<td>test</td>
<td>tttttttttttttttttttttttttttttttttttttttttttttttttttttt</td>
</tr>
<tr>
<td>test</td>
<td>tttttttttttttttttttttttttttttttttttttttttttttttttttttt</td>
</tr>
</table>
<div id="adjDiv" style="float:left; border: 1px solid red;">
Div next to the table
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
//Set height using the id of my div and the height of your table
$('#adjDiv').height($('#table').height());
});
</script>
</body>
</html>