it-swarm.com.ru

Bootstrap 4 Адаптивная таблица, горизонтальная и вертикальная прокрутка

Я использую bootstrap таблицы с Angular 6 в проекте, и мне удалось создать тело таблицы вертикальной прокрутки с помощью этого кода:

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

И 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 )
  } 

Но теперь, если есть много столбцов, это не выглядит хорошо.

// pic

Поэтому я тоже хотел добавить горизонтальную прокрутку, чтобы можно было прокручивать всю таблицу по горизонтали и только тело таблицы по вертикали. Чтобы сделать горизонтальную прокрутку, я использовал .table-responseive так:

<div class="table-responsive">
    <table class="table table-striped table-bordered" style="margin-bottom: 0">
    ...
    </table>
</div>

Но это работает только без вертикальной части прокрутки в CSS.

enter image description here

Я хочу совместить эти два способа прокрутки таблицы. Я изменил значения ширины в части css со 100% до статических значений px, например:

...
thead, tbody tr {
      display:table;
      width: 2000px;
      table-layout:fixed;
  }
  thead {
      width: calc( 2000px - 1em )
  } 

И это сработало, но мне нужно установить статическую ширину, и я не знаю, как я могу сделать это динамически (в зависимости от количества столбцов).

enter image description here

2
JCAguilera

Я исправил это так: сначала я отредактировал css, затем удалил часть thead и добавил немного содержимого в тело следующим образом:

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

Я также оставил .table-responsive div:

<div class="table-responsive">
    <table class="table table-striped table-bordered" style="margin-bottom: 0">
    ...
    </table>
</div>

Затем я вычислил --table-width в зависимости от количества столбцов и длины самого длинного имени столбца. Я сделал это с Angular, в моем компоненте .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';
}

Мне нужно запустить calculateTableWidth() в начале в ngOnInit() (или когда я определил массив tableColumns), а затем, когда я изменяю размер окна:

ngOnInit() {
  this.tableColumns = this.myAppService.getTableColumnsNames();
  this.calculateTableWidth();
}

@HostListener('window:resize', ['$event'])
onResize(event: any) {
  this.calculateTableWidth();
}

И вот как я это исправил. Теперь у меня есть красивый стол с вертикальной и горизонтальной прокруткой.

1
JCAguilera

Надеюсь, что это поможет любому органу разработать исправление заголовка угловой таблицы 6

scss

// Table related css start
        .deallist-tbl {
            width: 100%;
            .table-striped>tbody>tr:nth-child(odd)>td {
                background-color: #F9F9F9;
            }
            .table-hover tbody tr:hover td {
                background-color: #0099CC;
                color: $content-text-white;
            }
            .table-hover tbody tr.active td {
                background-color: #0099CC;
                color: $content-text-white;
            }
            table {
                border-collapse: collapse;
                width: 100%;
                overflow-x: scroll;
                display: block;
            }
            thead {
                background-color: #F5F1EF;
            }
            thead,
            tbody {
                display: block;
            }
            tbody {
                overflow-y: scroll;
                overflow-x: hidden;
                height: 650px;
            }
            td {
                min-width: 90px;
                height: 30px;
                border: solid 1px $border-color;
                overflow: hidden;
                text-overflow: Ellipsis;
                max-width: 100px;
                padding: 5px 5px 5px 10px;
                &.index-clm {
                    width: 35px;
                    min-width: 35px;
                    padding: 5px;
                }
            }
            th {
                font-size: 10px;
                font-weight: bold;
                min-width: 90px;
                height: 30px;
                overflow: hidden;
                text-overflow: Ellipsis;
                text-transform: uppercase;
                max-width: 100px;
                padding: 5px 5px 6px 10px;
                border-left: solid 1px $content-text-black;
                border-top: solid 1px $border-color;
                border-bottom: solid 1px $border-color;
                &:last-child {
                    border-right: solid 1px $content-text-black;
                }
                &.index-clm {
                    width: 35px;
                    min-width: 35px;
                    padding: 5px;
                }

            }
        } // Table related css end

HTML

<table  class="table table-striped table-hover mb-0" id="dataTable" #tblDealList (scroll)="scrollHandler($event)">
          <thead [style.width.px]="tblWidth">
            <tr>
              <th class="text-center index-clm">*</th>
              <th app-sortable-column columnName="Column1">Column 1</th>
              <th app-sortable-column columnName="Column2">Column 2</th>
              <th app-sortable-column columnName="Column3">Column 3</th>
              <th app-sortable-column columnName="Column4">Column 4</th>
              <th app-sortable-column columnName="Column5">Column 5</th>
              <th app-sortable-column columnName="Column6">Column 6</th>
              <th app-sortable-column columnName="Column7">Column 7</th>
              <th app-sortable-column columnName="Column8">Column 8</th>
              <th app-sortable-column columnName="Column9">Column 9</th>
              <th app-sortable-column columnName="Column10">Column 10</th>
              <th app-sortable-column columnName="Column11">Column 11</th>
              <th app-sortable-column columnName="Column12">Column 12</th>
              <th app-sortable-column columnName="Column13">Column 13</th>
              <th app-sortable-column columnName="Column14">Column 14</th>
              <th app-sortable-column columnName="Column15">Column 15</th>
              <th app-sortable-column columnName="Column16">Column 16</th>

            </tr>
          </thead>
          <tbody [style.width.px]="tblWidth">
            <tr *ngFor="let item of dealList; let i = index" [class.active]="activeCode===i" (click)="selectDealItem(content,item, i)"
              (dblclick)="show()">
              <td class="text-center index-clm">{{item.isModified ? '*' : ''}}</td>
              <td>{{item.Column1 }}</td>
              <td>{{item.Column2 }}</td>
              <td>{{item.Column3 }}</td>
              <td>{{item.Column4 }}</td>
              <td>{{item.Column5 }}</td>
              <td>{{item.Column6 }}</td>
              <td>{{item.Column7 }}</td>
              <td>{{item.Column8 }}</td>
              <td>{{item.Column9 }}</td>
              <td>{{item.Column10 }}</td>
              <td>{{item.Column11 }}</td>
              <td>{{item.Column12 }}</td>
              <td>{{item.Column13 }}</td>
              <td>{{item.Column14 }}</td>
              <td>{{item.Column15 }}</td>
              <td>{{item.Column16 }}</td>
            </tr>

          </tbody>
        </table>

Наиболее важная функция файла TS заключается в следующем

 /**
   * set table width when scrolling
   */
  @HostListener('window:scroll', ['$event'])
  scrollHandler(event) {
    this.tblWidth = this.tblWidthInitial + event.target.scrollLeft;
  }

Начальная ширина таблицы может быть рассчитана следующим образом

  @ViewChild('tblDealList') tblDealList: ElementRef;

Внутри ngOnInit

  this.tblWidthInitial = this.tblDealList.nativeElement.offsetWidth;

Окончательный результат

 enter image description here

0
Janith Widarshana