Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Floating horizontal scrollbar with mat-table in Angular

Is it possible to add a floating horizontal scrollbar to a mat-table in Angular 7 without JQuery or any other additional plugins?

I have a mat-table that shows 6 columns but also can dynamically add 100+ columns with the push of a button.
But then the layout breaks.

HTML-Part:

<button (click)="showLess()" mat-stroked-button class="show-button">Show Less</button>
<button (click)="showMore()" mat-stroked-button class="show-button">Show More</button>

<div class="component data component-card">
<mat-card *ngIf="dataSource?.filteredData" class="mat-card">
    <mat-paginator [length]="length" [pageSize]="100" [pageSizeOptions]="[100, 250, 500, 1000, 2000]" showFirstLastButtons> </mat-paginator>
    <mat-table [dataSource]="dataSource" matSort class="table">
        <ng-container class="container" *ngFor="let displayedColumn of displayedColumns" matColumnDef="{{ displayedColumn }}">
            <mat-header-cell class="header-cell" *matHeaderCellDef >
                <span mat-sort-header class="sort-header">{{ displayedColumn | uppercase }}</span>
                <input class="table-input" matInput (keyup)="applyFilter($event.target.value)" (focus)="setupFilter(displayedColumn)" placeholder="Filter"/>
            </mat-header-cell>
            <mat-cell class="cell" *matCellDef="let item">{{ item[displayedColumn] }}</mat-cell>
        </ng-container>
        <mat-header-row class="header-row" *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
        <mat-row class="row" *matRowDef="let row; columns: displayedColumns;"></mat-row>
    </mat-table>
</mat-card>

CSS-Part:

.data {
    display: block;
    width: 95vw;
    overflow: auto;

    .table {
        width: 100vw;
        max-width: 100%;
        overflow: auto;
        margin-bottom: 10px;
        display: table;
        border-collapse: collapse;
        margin: 0px;
        background-color: rgb(238, 238, 238);
}
    .row,
    .header-row {
        display: table-row;
        min-height: 36px !important;
}
    .cell,
    .header-cell {
        word-wrap: initial;
        display: table-cell;
        padding: 0px 5px;
        line-break: unset;
        width: fit-content;
        white-space: nowrap;
        overflow: hidden;
        vertical-align: middle;
        text-align: center;
}
    .header-row,
    .header-cell {
        margin: 0 auto;
        min-height: 100px !important;
        text-align: center;
        vertical-align: middle;
        align-self: center;
}
    .sort-header {
        display: flex;
        align-content: center;
        text-align: center;
        justify-content: center;
        font-size: 12pt;
}
    .header-cell {
        font-weight: bold;
    }
}

.mat-card {
    min-width: max-content;
    max-width: max-content;
}

If the overflows are both active then I have to scroll down to be able to scroll horizontally but the layout stays as it should. Only the mat-table and the div around it it will be scrolled and the elements above the mat-table (search fields etc.) are staying where they should. Everything stays in the middle of the screen.

If I deactivate the overflow from the div in the ".data" then the normal browser scrollbar appears and I don't have to scroll down anymore. But the mat-table expands the screen to the right on scrolling and the search fields above will stay on the left when scrolling horizontally which for me breaks the layout.

What I need would be a combination of both scrollbars which would be a floating scrollbar in my eyes. I would only scroll the mat-table but the rest stays in place.

Is there a way to accomplish that natively with CSS or Angular?

Demo: https://stackblitz.com/edit/angular-elm867?file=src%2Fapp%2Fapp.component.scss

If you click on Show More just see how the buttons behave when scroll after commentating "overflow: auto" in and out in the ".data".

Here's an image on how the table scrollbar should replace the normal scrollbar: enter image description here

like image 612
suckerp Avatar asked Mar 25 '19 09:03

suckerp


2 Answers

I hope this will be helpfull for others to add Horizontal Scrolling to mat-table and column width according to cell content.

.mat-table {
      overflow-x: scroll;
    }

.mat-cell,
.mat-header-cell {
    word-wrap: initial;
    display: table-cell;
    padding: 0px 10px;
    line-break: unset;
    width: 100%;
    white-space: nowrap;
    overflow: hidden;
    vertical-align: middle;
}
.mat-row,
.mat-header-row {
    display: table-row;
}
like image 192
Muhammad Sohail Avatar answered Oct 26 '22 15:10

Muhammad Sohail


i just add this css codes:

.mat-table {
    overflow-x: scroll;
}

.mat-row,
.mat-header-row {
    min-width: 800px;
}
like image 40
amin arghavani Avatar answered Oct 26 '22 14:10

amin arghavani