I'm using bootstrap tables with Angular 6 in a project, and I was able to create vertical scroll table-body with this code:
<table class="table table-striped table-bordered" style="margin-bottom: 0">
<thead> <!-- Column names -->
<tr>
<th scope="col">#</th>
<th scope="col">Col 1</th>
<th scope="col">Col 2</th>
<th scope="col">Col 3</th>
...
<th scope="col">Col N</th>
</tr>
</thead>
<tbody> <!-- Data -->
<tr>
<th scope="row">1</th>
<td>AAAAA</td>
<td>BBBBB</td>
<td>CCCCC</td>
...
<td>DDDDD</td>
</tr>
<tr>
<th scope="row">2</th>
<td>AAAAA</td>
<td>BBBBB</td>
<td>CCCCC</td>
...
<td>DDDDD</td>
</tr>
...
<tr>
<th scope="row">n</th>
<td>AAAAA</td>
<td>BBBBB</td>
<td>CCCCC</td>
...
<td>DDDDD</td>
</tr>
</tbody>
</table>
And css:
tbody {
display:block;
max-height:500px;
overflow-y:auto;
}
thead, tbody tr {
display:table;
width:100%;
table-layout:fixed;
}
thead {
width: calc( 100% - 1em )
}
But now, if there are a lots of columns it doesn't look good.
So I wanted to add a horizontal scroll too, so I could scroll the full table horizontally and only the table body vertically. To do the horizontal scroll I used .table-responsive like this:
<div class="table-responsive">
<table class="table table-striped table-bordered" style="margin-bottom: 0">
...
</table>
</div>
But it only works without the vertical scroll part in the css.
I want to combine this two ways to scroll the table. I changed the width values on the css part, from 100% to static px values like this:
...
thead, tbody tr {
display:table;
width: 2000px;
table-layout:fixed;
}
thead {
width: calc( 2000px - 1em )
}
And it worked, but I need to set a static width and I don't know how can I do this dynamically (depending on the number of columns).
To enable y-scrolling simply set the scrollY parameter to be whatever you want the container wrapper's height to be (any CSS measurement is acceptable, or just a number which is treated as pixels).
By setting postion: sticky and top: 0, we can create a fixed header on a scroll in HTML tables.
I fixed it this like this: First I edited the css, then I removed the thead
part, and added some content in the body like this:
body {
--table-width: 100%; /* Or any value, this will change dinamically */
}
tbody {
display:block;
max-height:500px;
overflow-y:auto;
}
thead, tbody tr {
display:table;
width: var(--table-width);
table-layout:fixed;
}
I also left the .table-responsive
div:
<div class="table-responsive">
<table class="table table-striped table-bordered" style="margin-bottom: 0">
...
</table>
</div>
Then I calculated --table-width
depending on the number of columns and length of the longest column name. I did this with Angular, in my component .ts:
calculateTableWidth() {
// Get the table container width:
const pageWidth = document.getElementById('tableCard').offsetWidth;
// Get the longest column name
const longest = this.tableColumns.sort(function (a, b) { return b.length - a.length; })[0];
// Calculate table width
let tableWidth = this.tableColumns.length * longest.length * 14;
// If the width is less than the pageWidth
if (tableWidth < (pageWidth - 10)) {
// We set tableWidth to pageWidth - scrollbarWidth (10 in my project)
tableWidth = pageWidth - 10;
}
// Then we update the --table-width variable:
document.querySelector('body').style.cssText = '--table-width: ' + tableWidth + 'px';
}
I need to run calculateTableWidth()
at the beginning in ngOnInit()
(or when I have defined the tableColumns array) and then when I resize the window:
ngOnInit() {
this.tableColumns = this.myAppService.getTableColumnsNames();
this.calculateTableWidth();
}
@HostListener('window:resize', ['$event'])
onResize(event: any) {
this.calculateTableWidth();
}
And that's how I fixed this. Now I have a good looking table, with vertical and horizontal scrolling.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With