I have a little problem with style sticky header in my data table. I wrote simple Angular component and specific directive:
sticky.directive.ts
#Directive({
selector: '[sticky]'
})
export class StickyDirective {
constructor(private _element: ElementRef, private _window: WindowRef) {
console.log('debug')
}
#HostListener('window:scroll', ['$event'])
handleScrollEvent(e) {
if (this._window.nativeWindow.pageYOffset > 100) {
this._element.nativeElement.classList.add('stick');
} else {
this._element.nativeElement.classList.remove('stick');
}
}
}
The purpose of the directive is to add a class stick if user scroll below header. As a result, table header should be visible for user, even if he scroll long table. stick class look like that:
.stick {
position: fixed;
top: 55px;
}
and part of my some.component.html (and use directive on thead element) look like:
<table class=" table table-bordered ">
<thead sticky>
<tr>
<th width="40%">Name
</th>
<th width="10%">Priority
</th>
<th width="25%">Date created
</th>
<th width="25%">Date modified
</th> </tr> </thead> <tbody> <tr *ngFor="let r of entitiesFiltered">
<td>
<div class="table-cell-flex">
<div class="cell-content">
{{r.name}}
</div>
</div>
</td>
<td>
<div class="table-cell-flex">
<div class="cell-content">
{{r.priority}}
</div>
</div>
</td>
...
My code meet basic functionality. It means that header stays in the same place during scroll page, but header width and columns width change. It's look like:
Question:
Anyone can tell me how can I should style my table, that fixed header does not change form/shape table? Is it possible?
you get width any columns with javaScript then setting to header with px in position fixed or absolute,
or with html and code:
<div class="table-wrapper content">
<!-- overall wrapper -->
<table>
<!-- header -->
<thead>
<tr>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
</tr>
</thead>
</table>
</div>
<div class="table-body-wrapper" style="position: relative; overflow: visible;">
<!-- the element with the custom scrollbar -->
<table>
<!-- body -->
<tbody>
<!-- auto-generated data (see js function below) -->
<tr>
<td>Row 1, Column 1</td>
<td>Row 1, Column 2</td>
<td>Row 1, Column 3</td>
</tr>
<tr>
<td>Row 2, Column 1</td>
<td>Row 2, Column 2</td>
<td>Row 2, Column 3</td>
</tr>
<tr>
<td>Row 3, Column 1</td>
<td>Row 3, Column 2</td>
<td>Row 3, Column 3</td>
</tr>
<tr>
<td>Row 4, Column 1</td>
<td>Row 4, Column 2</td>
<td>Row 4, Column 3</td>
</tr>
<tr>
<td>Row 5, Column 1</td>
<td>Row 5, Column 2</td>
<td>Row 5, Column 3</td>
</tr>
</tbody>
</table>
</div>
I faced the same issue.
In order to solve it, I created a simple hack where I set the fixed width of columns in sticky header and duplicated the sticky header under the table (in order to preserve the width of column names' content.
My solution is based on Bootstrap 4 and Angular 6.
example.component.html:
<table class="table">
<thead>
<tr>
<th #tableColumn1>Column 1</th>
<th #tableColumn2>Column 2</th>
<th #tableColumn3>Column 3</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let message of messages">
<td>{{ message.title }}</td>
<td>{{ message.author }}</td>
<td>{{ message.created_at }}</td>
</tr>
</tbody>
</table>
<table class="table" [class.d-none]="!showFixedTableHeader">
<thead>
<tr [class.sticky]="showFixedTableHeader">
<th [width]="tableColumn1.offsetWidth">Column 1</th>
<th [width]="tableColumn2.offsetWidth">Column 2</th>
<th [width]="tableColumn3.offsetWidth">Column 3</th>
</tr>
</thead>
</table>
example.component.ts
import {Component, HostListener} from '#angular/core';
#Component({
templateUrl: './example.component.html',
styleUrls: ['./example.component.css']
})
export class ExampleComponent {
showFixedTableHeader: boolean = false;
#HostListener('window:scroll')
onScroll() {
const pageTopOffset = window.pageYOffset;
if (pageTopOffset > 285) {
this.showFixedTableHeader = true;
} else {
this.showFixedTableHeader = false;
}
}
#HostListener('window:resize')
onResize() {
// Do nothing.
// It will automatically trigger to update the bound properties in template.
}
}
example.component.css
tr.sticky {
top: 60px;
position: fixed;
z-index: 99;
}
I don't think you need the angular directive, it's overriding the styles, which specify the width, when it adds class "stick".
You can just fix the position of your table head and set a higher z-index on it so when it does scroll, the body doesn't show through.
See codepen example:
thead{
position:fixed;
z-index:2;
...
}
tbody{
position:absolute;
z-index:1;
...
}
https://codepen.io/ciammarino/pen/vmqzLL
I have just discovered:
position: sticky
https://developer.mozilla.org/fr/docs/Web/CSS/position#Positionnement_adh%C3%A9rent_(sticky)
Related
I'm using a Vuetify table with multiple columns like so
Reproduction link
<v-table>
<thead>
<tr>
<th v-for="index in 10">Header {{ index }}</th>
</tr>
</thead>
<tbody>
<tr v-for="rowIndex in 10">
<td v-for="columnIndex in 10">
<v-card>
<v-card-title>Cell in row {{ rowIndex }} in column {{ columnIndex }}</v-card-title>
</v-card>
</td>
</tr>
</tbody>
</v-table>
For smaller screen sizes the horizontal scrollbar is perfectly fine. But there is a "print mode" where horizontal scrollbars make no sense ( data loss on PDF file ). So regardless of the actual table width I would like to prevent a horizontal scrollbar ( I'm aware that this might look very ugly ). I think this problem is not related to Vuetify, I think this also applies for plain HTML.
I tried to disable the horizontal scrollbar via overflow-x: hidden;
div {
overflow-x: hidden;
}
td {
padding: 20px;
background: red;
}
<div>
<table>
<thead>
<th>Header 1</th>
<th>Header 2</th>
<th>Header 3</th>
<th>Header 4</th>
<th>Header 5</th>
<th>Header 6</th>
<th>Header 7</th>
<th>Header 8</th>
<th>Header 9</th>
<th>Header 10</th>
</thead>
<tbody>
<tr>
<td>I'm a cell in row 1 in column 1</td>
<td>I'm a cell in row 1 in column 2</td>
<td>I'm a cell in row 1 in column 3</td>
<td>I'm a cell in row 1 in column 4</td>
<td>I'm a cell in row 1 in column 5</td>
<td>I'm a cell in row 1 in column 6</td>
<td>I'm a cell in row 1 in column 7</td>
<td>I'm a cell in row 1 in column 8</td>
<td>I'm a cell in row 1 in column 9</td>
<td>I'm a cell in row 1 in column 10</td>
</tr>
</tbody>
</table>
</div>
but unfortunately that didn't help. As you can see there is some content loss on the right side.
Do you have any ideas how to tell the content to shrink as much as possible?
you need to apply css rules differently for print screen
#media print {
body {
overflow-x: visible
}
}
here body is the first parent element of table, you can apply it to the immediate parent of table and it will work in print mode.
overflow-x: visible property will print it adjusting the data in new line in print screen
This question already has answers here:
display table height not always respected
(3 answers)
Closed 5 years ago.
I created an html table and I am trying to set a max-height and height properties to itbut the table don't accept themI am using this code
HTML
<table class="table table-striped table-hover" id="Table">
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
<th>Column 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>Row 0 0</td>
<td>Row 0 1</td>
<td>Row 0 2</td>
<td><a id="table-buttons" class="btn btn-primary">Row 0 3</a></td>
</tr>
<tr>
<td>Row 1 0</td>
<td>Row 1 1</td>
<td>Row 1 2</td>
<td><a id="table-buttons" class="btn btn-primary">Row 1 3</a></td>
</tr>
<tr>
<td>Row 2 0</td>
<td>Row 2 1</td>
<td>Row 2 2</td>
<td><a id="table-buttons" class="btn btn-primary">Row 2 3</a></td>
</tr>
</tbody>
</table>
CSS
#Table {
width: 600px;
max-width: 600px;
height: 210px;
max-height: 210px;
overflow-y: auto;
}
td {
width: 150px;
max-width: 150px;
}
the table:
The specified height and max-heightmustn't allow the table to carry more than these three rows and the headerbut when I add another row the table
totally ignores the height and the max-heightand expands to fit the four rows
I want the table to show a scrollbar as a result of the overflow-y: auto propertybut the didn't happen
I am using This Bootstrap style
please help
Setting table height is overruled by the table content. See this answer: display table height not always respected
You could work around it by wrapping a div around it (and setting the height and overflow on the div).
Put the table in a div, and set the height and width for that div:
<div id="Table">
<table class="table table-striped table-hover">
<!-- Table rows and data -->
</table>
</div>
Note: remove the id from the table tag.
Just wrap a div around the table, checkout this Codepen for a demo
You should target the class, not the ID.
Like this:
.table {
width: 600px;
max-width: 600px;
height: 210px;
max-height: 210px;
overflow-y: auto;
}
This is an assignment question.
The table above is what I need to make. The table below is what I came up with:
My code:
<!DOCTYPE html>
<html>
<head>
<title>Question Two</title>
<meta charset="UTF-8">
</head>
<body>
<h2>Nested Tables</h2>
<table border="1">
<tr>
<th>Header column 1</th>
<th>Header column 2</th>
<th>Header column 3</th>
<th>Header column 4</th>
</tr>
<tr>
<td>Row 2 - Item 1</td>
<td>Row 2 - Item 2</td>
<td rowspan="2">
<h4>Row 2: Nested Table 1</h4>
<table border="1">
<tr>
<th>Row 1 Header</th>
<td>item</td>
</tr>
<tr>
<th>Row 2 Header</th>
<td>item</td>
</tr>
<tr>
<th>Row 3 Header</th>
<td>item</td>
</tr>
</table>
</td>
<td>Row 2 - Item 4<br/>A second line</td>
</tr>
<tr>
<td>
<h4>Row 3: Nested Table 2</h4>
<table border=1>
<tr>
<th>Row 1 Header</th>
<td>item</td>
</tr>
<tr>
<th>Row 2 Header</th>
<td>item</td>
</tr>
</table>
</td>
<td>Row 3 - Item 2</td>
<td rowspan="2">Row 3 - Item 3</td>
</tr>
<tr>
<td>Row 4 - Item 1</td>
<td>Row 4 - Item 2</td>
<td>Row 4 - Item 3</td>
</tr>
<tr>
<td colspan="4">Row 5 - Last row of outer table</td>
</tr>
</table>
</body>
</html>
Two things are different: the font and line spacing of Nested Table 1 and 2.
As per the font, is there a way to set a default font for all HTML documents to use? If so, how?
For the spacing, I have no idea. I tried all kinds of combinations of <br>, <pre>, <div>.. etc. I'm pretty sure it's not a browser issue that caused the erroneous result (tried multiple browsers--I'm using IE, running on Windows 7). Any ideas?
Thank you.
This is just a wild guess but the font you're looking for may be "Calibri" or something very similar. You can add the font-family as an inline style to your body tag and everything in the table will inherit the font.
<body style="font-family:Calibri;"> and here's a demo of it in action.
The spacing seems fine as is, however if you need to make adjustments you can do so with padding, margin, or even cellpadding.
This will pad the space in all the cells by 10: <table border="1" cellpadding="10">
This will pad the top of the cell by 10px: <td rowspan="2" style="padding-top:10px;">
As per the font, is there a way to set a default font for all HTML documents to use? If so, how?
If it's something for "all HTML documents" to use, then it would be a browser setting. You're probably on your own for that one. But if you want something for all of the content in this document to use, that's easy with CSS. Something like this:
<style>
body {
font-family: Arial;
font-size: 1em;
color: #000;
}
</style>
Putting that in the head of the HTML would apply that styling to the entire contents of the body tag, including all descendants. (You can also put the CSS code in a separate file and use a <link> tag to reference it in the head. As the code grows in complexity, this quickly becomes a preferred approach.)
For the spacing, I have no idea. I tried all kinds of combinations of <br>, <pre>, <div>.. etc.
I'd use CSS for this as well. First, identify the element(s) you want to target. An id or a class is often a good approach. For example:
<td rowspan="2" id="column3Cell">
Then in the CSS you can target that element and apply styling to it:
#column3Cell {
padding-top: 10px;
}
Adjust as necessary. Since the goal here is to replicate a screen shot as exactly as possible, approximating it is going to take some tweaking and trial-and-error. But there is a lot you can do with CSS styles here.
<table border="1">
<thead>
<th>Header Column 1</th>
<th>Header Column 2</th>
<th>Header Column 3</th>
<th>Header Column 4</th>
</thead>
<tbody>
<tr>
<td rowspan="">Row 2 - Item 1</td>
<td>Row 2 -Item 2</td>
<td rowspan="2">Row 2 : Nested Table1
<br>
<br>
<table border="1">
<tr>
<th>Row 1 Header</th>
<td>item</td>
</tr>
<tr>
<th>Row 2 Header</th>
<td>item</td>
</tr>
<tr>
<th>Row 3 Header</th>
<td>item</td>
</tr>
</table>
</td>
<td>Row 2 : Item 4 <br> A second Line</td>
</tr>
<tr>
<td>
<br>
Row 3- Nested Table 2
<br>
<br>
<table border="1">
<tr>
<th>Row 1 Header</th>
<td>item</td>
</tr>
<tr>
<th>Row 2 Header</th>
<td>item</td>
</tr>
</table>
</td>
<td>Row 3 -item 2</td>
<td rowspan="2">Row 3 - Item 3</td>
</tr>
<tr>
<td>Row 4 - item 1 </td>
<td>Row 4 - item 2</td>
<td>Row 4 - item 3 </td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4">Row 5-Last row of outer table</td>
</tr>
</tfoot>
</table>
I have 2 tables using DataTable :
top: exact match
bottom : related
Here is what they look like right now.
As you can see that, there is no need to show the table header on the second table. I want to hide it.
I have tried using this on my CSS :
Since the class = inventory_related
.inventory_related table thead {
display:none;
}
I also tried to take off the whole :
<thead class="thin-border-bottom ">
<th>Catalog # </th>
<th>Description</th>
<th>Available Vials</th>
</thead>
This doesn't work either.
Anyone have any suggestion on how do I hide my 2nd table header ?
Thanks.
In my case, setting
.inventory_related thead {
display:none;
}
messed with column widths, while
.inventory_related thead {
visibility: collapse;
}
seems to be working.
<table>
<thead style='display:none;'>
<th>header 1</th>
<th>header 2</th>
</thead>
<tbody>
<td>row value 1</td>
<td>row value 2</td>
</tbody>
</table>
Please see the following code as an example:
.inventory_related thead {
display: none;
}
<table>
<thead>
<th>header 1</th>
<th>header 2</th>
</thead>
<tbody>
<td>row value 1</td>
<td>row value 2</td>
</tbody>
</table>
<table class='inventory_related'>
<thead>
<th>header</th>
<th>header 2</th>
</thead>
<tbody>
<td>row value 3</td>
<td>row value 4</td>
</tbody>
</table>
if the class of <table> is inventory_related then write the following css
.inventory_related thead {
display:none;
}
If you want to do it in jQuery(js) then you can simply do:
$("#datatableId").css("display", "none");
where 'datatableId' is the ID of your table or some div tag which contains the table.
According to this article at W3 Schools, one can create a basic table in HTML like this:
<table border="1">
<tr>
<td>row 1, cell 1</td>
<td>row 1, cell 2</td>
</tr>
<tr>
<td>row 2, cell 1</td>
<td>row 2, cell 2</td>
</tr>
</table>
From above, it appears that one enters data by rows.
I have a situation where I need to enter all of the data by columns. Is something like this possible?
<table border="1">
<tc>
<td>row 1, cell 1</td>
<td>row 2, cell 1</td>
</tc>
<tc>
<td>row 1, cell 2</td>
<td>row 2, cell 2</td>
</tc>
</table>
In modern browsers you can achieve this by redefining the TR and TD tags behavior in CSS. Given the HTML in your question attach the next CSS style:
table {
display: table;
}
table tr {
display: table-cell;
}
table tr td {
display: block;
}
<table border="1">
<tr>
<td>row 1, cell 1</td>
<td>row 2, cell 1</td>
</tr>
<tr>
<td>row 1, cell 2</td>
<td>row 2, cell 2</td>
</tr>
</table>
You can render tables in columns by using a table within a table...
<table>
<tr>
<td>
<table>
<thead>
<tr>
<td>column 1 header 1</td>
</tr>
</thead>
<tbody>
<tr>
<td>column 1 row 1</td>
</tr>
<tr>
<td>column 1 row 2</td>
</tr>
</tbody>
</table>
</td>
<td>
<table>
<thead>
<tr>
<td>column 2 header 1</td>
</tr>
</thead>
<tbody>
<tr>
<td>column 2 row 1</td>
</tr>
<tr>
<td>column 2 row 2</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>
You're best bet is to render the table by rows, and then use javascript to invert the table
http://jsfiddle.net/CsgK9/2/
The following code will invert a table (this sample code uses jquery)
$("table").each(function() {
var $this = $(this);
var newrows = [];
$this.find("tr").each(function(){
var i = 0;
$(this).find("td").each(function(){
i++;
if(newrows[i] === undefined) { newrows[i] = $(""); }
newrows[i].append($(this));
});
});
$this.find("tr").remove();
$.each(newrows, function(){
$this.append(this);
});
});
UPDATE:
Here is a version that works with th elements as well:
http://jsfiddle.net/zwdLj/
Just did this by using a bunch of uls filled with lis, seemed a lot cleaner than anything I could find. You'll have to do something like adding a class to all the uls and setting its style to display: inline-table.
#* pseudo html/razor *#
#foreach(var col in columns){
<ul class='tableColumn'>
foreach(var data in col){
<li>data</li>
}
</ul>
}
and some styling
.tableColumn {
border: 1px solid;
display: inline-table;
}
You can always create a parent element (the table), and then inside the table you can create in-line block elements with limited width to serve as your columns, that way any content you add to those child columns will follow the downward pattern, then to make the grid-like pattern just make sure to set the height of the elements within the column, like so Using the list to display content:
<div id="your_table">
<span style="width: 25%" id="fist_column"> <ul></ul></span>
<span style="width: 25%" id="second_column"><ul></ul></span>
<span style="width: 25%" id="third_column"><ul></ul></span>
<span style="width: 25%" id="fourth_column"><ul></ul></span>
</div>
I was in same situation where I have to add the data by column. But, this problem is solved in a simple method. I have used twig in this example, but you will get it easily.
<table>
<tr>
<th>id</th>
<th>title</th>
<th>ISBN</th>
<th>author_id</th>
<th>publisher_id</th>
</tr>
{% for book in books %} //for loop is used before the <tr> tag
<tr>
<td>{{ book.id }}</td>
<td>{{ book.title }}</td>
<td>{{ book.isbn }}</td>
<td>{{ book.publisher.id }}</td>
<td>{{ book.author.id }}</td>
{% endfor %}
</tr>
Note:{{ this is data to print }}