web-dev-qa-db-fra.com

Barre de défilement horizontale flottante avec mat-table en Angular

Est-il possible d'ajouter une barre de défilement horizontale flottante à un mat-table in Angular 7 sans JQuery ou tout autre plugin supplémentaire?

J'ai un mat-table qui affiche 6 colonnes mais peut également ajouter dynamiquement plus de 100 colonnes en appuyant sur un bouton.
Mais alors la disposition se brise.

Partie HTML:

<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>

Partie CSS:

.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;
}

Si les débordements sont tous les deux actifs, je dois faire défiler vers le bas pour pouvoir faire défiler horizontalement, mais la mise en page reste comme elle le devrait. Seuls le mat-table et le div qui l'entoure défileront et les éléments au-dessus du mat-table (champs de recherche, etc.) resteront là où ils devraient. Tout reste au milieu de l'écran.

Si je désactive le débordement de la div dans le ".data" alors la barre de défilement normale du navigateur apparaît et je n'ai plus besoin de faire défiler vers le bas. Mais le mat-table étend l'écran vers la droite lors du défilement et les champs de recherche ci-dessus resteront à gauche lors du défilement horizontal, ce qui pour moi rompt la mise en page.

Ce dont j'ai besoin serait une combinaison des deux barres de défilement qui serait une barre de défilement flottante à mes yeux. Je ne ferais que faire défiler la table de tapis mais le reste reste en place.

Existe-t-il un moyen d'accomplir cela nativement avec CSS ou Angular?

Démo: https://stackblitz.com/edit/angular-Elm867?file=src%2Fapp%2Fapp.component.scss

Si vous cliquez sur Afficher plus, voyez comment les boutons se comportent lors du défilement après avoir commenté "overflow: auto" dans et hors du ".data".

Voici une image sur la façon dont la barre de défilement du tableau doit remplacer la barre de défilement normale: enter image description here

2
suckerp

J'espère que cela aidera les autres à ajouter le défilement horizontal à la table des tapis et à la largeur des colonnes en fonction du contenu des cellules.

.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;
}
1
Muhammad Sohail

dans votre stackblitz existant , Besoin d'un changement pour y parvenir ...

Dans SCSS, définissez la classe comme: mat-paginator{width:97vw;}

1
Akber Iqbal

Ajoutez ce qui suit à styles.css pour supprimer la barre de défilement horizontale

html,
body {
  margin: 0 !important;
  padding: 0 !important;
}

Ajoutez également pour apporter un défilement horizontal dans .table si des colonnes supplémentaires sont débordées.

.mat-card {
    min-width: 100% !important;
    max-width: 100% !important;
}
.table {
  display: block !important;
}

Démo Stackblitz avec des données de table ajustées après l'ajout dynamique de colonnes


Mise à jour 1:

Correction du max-height pour le conteneur div .data pour fixer la barre de défilement horizontale dans le conteneur.

.data {
  max-height: 500px;
  overflow: auto;
}

Démo avec hauteur maximale fixe sur le conteneur extérieur pour la fixation des parchemins

0
Abhishek Kumar