fixed header and scrollable body in table in html angular


Topic: fixed header and scrollable body in table in html angular

Frederic pro premium priority asked 6 years ago

Hello,

I’m using « Table vertical scroll » to display data:

{{header}} {{item.name}} {{item.surname}} {{item.country}} {{item.city}} {{item.position}} {{item.age}}

Screenshot 1

If the screen size gets smaller, an horizontal scroll bar shows automatically to allow the table to scroll:

Screenshot 2

Now I need to turn the « Table vertical scroll » into a table with a fixed header and with a body scrolling vertically.

I used html and the following css to get this output :

tbody {
  display: block;
  overflow: auto;
  height: 500px;
  width: 100%;
}

thead tr {
  display: table;
  width: 100%;
  table-layout: fixed;
}

thead, tbody tr {
  display: table;
  width: 100%;
  table-layout: fixed;
}

thead {
  width: calc( 100% - 1em )
}

{{header}} {{item.name}} {{item.surname}} {{item.country}} {{item.city}} {{item.position}} {{item.age}}

Screenshot 3

I have a problem : when the screen size gets smaller, none of the horizontal scroll bars appears and the table columns are too close.

Screenshot 4

How could I get a working table like pictures 1 and 2, with the same features, but with a fixed header?

Thanks


Damian Gemza staff answered 6 years ago

Dear @Frederic

Okay, now I think that I get it.

Please take a look at the below code. What I have changed?

1) I have added style="overflow: auto" to the div which is parent for the whole table element,

2) I have added .table-responsive class to the table element,

3) I have set the fixed td width with css

.html:

<div mdbModal #formTestModal="mdbModal" class="modal fade top mt-3" style="overflow-y: auto" id="listTestModalTop" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
     aria-hidden="true" [config]="{ignoreBackdropClick: true, keyboard: false}">

  <div class="modal-header">
    <p class="heading lead">List</p>
    <button type="button" class="close" data-dismiss="modal" aria-label="Close" (click)="hide()">
      <span aria-hidden="true" class="white-text">&times;</span>
    </button>
  </div>

  <div class="modal-body">

    <div style="overflow: auto;">
      <div class="float-center mb-1">
        <h3 class="card-header text-center font-weight-bold py-2">List</h3>
      </div>

      <table mdbTable mdbTableScroll scrollY="true" class="table table-striped text-center mb-5 table-responsive" bordered="true">

        <thead>
        <tr>
          <th class="text-center">
            <mdb-checkbox [checked]="itemsAllChecked" (change)="onChkAll($event)"></mdb-checkbox>
          </th>
          <th *ngFor="let header of headers" class="align-middle">{{header}}</th>
        </tr>
        </thead>

        <tbody>
        <tr *ngFor="let item of listInfo; let id = index; let rowEven = even" [class.card-header]="rowEven">
          <td class="text-center">
            <mdb-checkbox [id]="item.id" [checked]="item.check" (change)="onChkChange($event)"></mdb-checkbox>
          </td>
          <td class="align-middle">{{item.name}}</td>
          <td class="align-middle">{{item.surname}}</td>
          <td class="align-middle">{{item.country}}</td>
          <td class="align-middle">{{item.city}}</td>
          <td class="align-middle">{{item.position}}</td>
          <td class="align-middle">{{item.age}}</td>
        </tr>
        </tbody>

      </table>
    </div>
  </div>

</div>

<button mdbBtn color="primary" (click)="show()">Show</button>

.scss:

tbody {
  display: block;
  overflow: auto;
  height: 500px;
  width: 100%;
}

thead tr {
  display: table;
  width: 100%;
  table-layout: fixed;
}

thead, tbody tr {
  display: table;
  width: 100%;
  table-layout: fixed;
}

thead {
  width: calc(100% - 1em)
}

td {
  width: 70px;
}

Best Regards,

Damian


Frederic pro premium priority answered 6 years ago

HTML first table:

<table mdbTable mdbTableScroll scrollY="true" maxHeight="500" class="table table-striped text-center vertical mb-5" bordered="true">

<thead>
  <tr>
    <th class="text-center">
      <mdb-checkbox [checked]="itemsAllChecked" (change)="onChkAll($event)"></mdb-checkbox>
    </th>
    <th *ngFor="let header of headers" class="align-middle">{{header}}</th>
  </tr>
</thead>

<tbody>
  <tr *ngFor="let item of listInfo; let id = index; let rowEven = even" [class.card-header]="rowEven">
    <td class="text-center">
      <mdb-checkbox [id]="item.id" [checked]="item.check" (change)="onChkChange($event)"></mdb-checkbox>
    </td>
    <td class="align-middle">{{item.name}}</td>
    <td class="align-middle">{{item.surname}}</td>
    <td class="align-middle">{{item.country}}</td>
    <td class="align-middle">{{item.city}}</td>
    <td class="align-middle">{{item.position}}</td>
    <td class="align-middle">{{item.age}}</td>
  </tr>
</tbody>

HTML second Table:

<table mdbTable mdbTableScroll scrollY="true" class="table table-striped text-center vertical mb-5" bordered="true">

<thead>
  <tr>
    <th class="text-center">
      <mdb-checkbox [checked]="itemsAllChecked" (change)="onChkAll($event)"></mdb-checkbox>
    </th>
    <th *ngFor="let header of headers" class="align-middle">{{header}}</th>
  </tr>
</thead>

<tbody>
  <tr *ngFor="let item of listInfo; let id = index; let rowEven = even" [class.card-header]="rowEven">
    <td class="text-center">
      <mdb-checkbox [id]="item.id" [checked]="item.check" (change)="onChkChange($event)"></mdb-checkbox>
    </td>
    <td class="align-middle">{{item.name}}</td>
    <td class="align-middle">{{item.surname}}</td>
    <td class="align-middle">{{item.country}}</td>
    <td class="align-middle">{{item.city}}</td>
    <td class="align-middle">{{item.position}}</td>
    <td class="align-middle">{{item.age}}</td>
  </tr>
</tbody>


Damian Gemza staff answered 6 years ago

Dear @Frederic

Could you please provide me with the .ts code of your tables? I would like to get the full code when I need to debug your problem.

Best Regards,

Damian


Frederic pro premium priority answered 6 years ago

Dear @Damian Gemza

here is the full code of the component:

list-test.component.html

<div mdbModal #formTestModal="mdbModal" class="modal fade top mt-3" style="overflow-y: auto" id="listTestModalTop" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
 aria-hidden="true" [config]="{ignoreBackdropClick: true, keyboard: false}">

  <div class="modal-header">
    <p class="heading lead">List</p>
    <button type="button" class="close" data-dismiss="modal" aria-label="Close" (click)="hide()">
      <span aria-hidden="true" class="white-text">&times;</span>
    </button>
  </div>

  <div class="modal-body">

    <div>
      <div class="float-center mb-1">
        <h3 class="card-header text-center font-weight-bold py-2">List</h3>
      </div>

      <table mdbTable mdbTableScroll scrollY="true" class="table table-striped text-center vertical mb-5" bordered="true">

        <thead>
          <tr>
            <th class="text-center">
              <mdb-checkbox [checked]="itemsAllChecked" (change)="onChkAll($event)"></mdb-checkbox>
            </th>
            <th *ngFor="let header of headers" class="align-middle">{{header}}</th>
          </tr>
        </thead>

        <tbody>
          <tr *ngFor="let item of listInfo; let id = index; let rowEven = even" [class.card-header]="rowEven">
            <td class="text-center">
              <mdb-checkbox [id]="item.id" [checked]="item.check" (change)="onChkChange($event)"></mdb-checkbox>
            </td>
            <td class="align-middle">{{item.name}}</td>
            <td class="align-middle">{{item.surname}}</td>
            <td class="align-middle">{{item.country}}</td>
            <td class="align-middle">{{item.city}}</td>
            <td class="align-middle">{{item.position}}</td>
            <td class="align-middle">{{item.age}}</td>
          </tr>
        </tbody>

      </table>
    </div>

  </div>

</div>

list-test.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';

import { ModalDirective, MdbCheckboxChange } from 'ng-uikit-pro-standard';

@Component({ selector: 'app-list-test', templateUrl: './list-test.component.html', styleUrls: ['./list-test.component.css'] }) export class ListTestComponent implements OnInit { @ViewChild('formTestModal') formListTestModal: ModalDirective;

public headers: Array = new Array("Name", "Surname", "Country", "City", "Position", "Age"); public listInfo: Array = new Array();

constructor() { this.listInfo = [ { id: 1, check: false, name: "Kate", surname: "Moss", country: "USA", city: "New York City", position: "Web Designer", age: 23 }, { id: 2, check: false, name: "Anna", surname: "Wintour", country: "United Kingdom", city: "London", position: "Frontend Developer", age: 36 }, { id: 3, check: false, name: "Tom", surname: "Bond", country: "Spain", city: "Madrid", position: "Photographer", age: 25 }, { id: 4, check: false, name: "Jerry", surname: "Horwitz", country: "Italy", city: "Bari", position: "Editor-in-chief", age: 41 }, { id: 5, check: false, name: "Janis", surname: "Joplin", country: "Poland", city: "Warsaw", position: "Video Maker", age: 39 }, { id: 6, check: false, name: "Gary", surname: "Winogrand", country: "Germany", city: "Berlin", position: "Photographer", age: 37 }, { id: 7, check: false, name: "Angie", surname: "Smith", country: "USA", city: "San Francisco", position: "Teacher", age: 52 }, { id: 8, check: false, name: "John", surname: "Mattis", country: "France", city: "Paris", position: "Actor", age: 28 }, { id: 9, check: false, name: "Otto", surname: "Morris", country: "Germany", city: "Munich", position: "Singer", age: 35 }, { id: 10, check: false, name: "Kate junior", surname: "Moss", country: "USA", city: "New York City", position: "Web Designer", age: 13 }, { id: 11, check: false, name: "Anna junior", surname: "Wintour", country: "United Kingdom", city: "London", position: "Frontend Developer", age: 26 }, { id: 12, check: false, name: "Tom junior", surname: "Bond", country: "Spain", city: "Madrid", position: "Photographer", age: 15 }, { id: 13, check: false, name: "Jerry junior", surname: "Horwitz", country: "Italy", city: "Bari", position: "Editor-in-chief", age: 31 }, { id: 14, check: false, name: "Janis junior", surname: "Joplin", country: "Poland", city: "Warsaw", position: "Video Maker", age: 29 }, { id: 15, check: false, name: "Gary junior", surname: "Winogrand", country: "Germany", city: "Berlin", position: "Photographer", age: 27 }, { id: 16, check: false, name: "Angie junior", surname: "Smith", country: "USA", city: "San Francisco", position: "Teacher", age: 42 }, { id: 17, check: false, name: "John junior", surname: "Mattis", country: "France", city: "Paris", position: "Actor", age: 18 } ]; }

ngOnInit() { }

public show() { this.formListTestModal.show(); }

public hide() { this.formListTestModal.hide(); }

get itemsAllChecked() { let bStatus: boolean = true; this.listInfo.forEach(i => bStatus = i.check && bStatus); return bStatus; }

public onChkAll(event: MdbCheckboxChange): void { this.listInfo.forEach(i => i.check = event.element.checked); }

public onChkChange(event: MdbCheckboxChange): void { this.listInfo[Number(event.element.id) - 1].check = event.element.checked; } }

interface IListItem { id: number; check: boolean; name: string | null; surname: string | null; country: string | null; city: string | null; position: string | null; age: number | null; }

list-test.component.css

tbody { display: block; overflow: auto; height: 500px; width: 100%; }

thead tr { display: table; width: 100%; table-layout: fixed; }

thead, tbody tr { display: table; width: 100%; table-layout: fixed; }

thead { width: calc( 100% - 1em ) }

Thanks


Frederic pro premium priority answered 6 years ago

Dear @Damian,

It works well.

Thanks.


FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Closed

Specification of the issue
  • User: Pro
  • Premium support: Yes
  • Technology: MDB Angular
  • MDB Version: MDB5 2.3.0
  • Device: Computer and SmartPhone
  • Browser: Edge and Chrome
  • OS: Windows 10
  • Provided sample code: No
  • Provided link: Yes