a minute ago

複数の行、列をテーブルのヘッダーとして固定したtable


vue-bootstrapのb-tableを使ったサンプル

複数の行、列をテーブルのヘッダーとして固定。

header1 header2
Row ID
A
B
C
1012
2012
3012
4012
5012
6012
7012
8012
9012
10012
header1 header2
Cols D
Cols E
Cols F
Cols G
Cols H
Cols I
Cols J
Cols K
Cols L
34567891011
34567891011
34567891011
34567891011
34567891011
34567891011
34567891011
34567891011
34567891011
34567891011

コード

b-tableを4つ配置し、スクロールを連動させる。

<template>
  <div style="display: grid; grid-template-columns: 300px 1fr;">
    <b-table
      id="left-header"
      class="l_table l_left l_header"
      :sticky-header="stickyHeader"
      :no-border-collapse="noCollapse"
      :items="items"
      :fields="headFields"
      responsive
      style="overflow: auto;"
      bordered
    >
      <!-- We are using utility class `text-nowrap` to help illustrate horizontal scrolling -->
      <template #thead-top="data">
        <b-tr>
          <b-th colspan="2">header1</b-th>
          <b-th colspan="2">header2</b-th>
        </b-tr>
      </template>

      <template #head(id)="scope">
        <div class="text-nowrap">Row ID</div>
      </template>

      <template #head()="scope">
        <div class="text-nowrap">
          {{ scope.label }}
        </div>
      </template>
      <template #cell()="data">
      </template>
    </b-table>
    <b-table
      id="right-header"
      class="l_table l_right l_header"
      :sticky-header="stickyHeader"
      :no-border-collapse="noCollapse"
      :items="items"
      :fields="tailFields"
      responsive
      style="overflow: auto;"
      bordered
    >
      <template #thead-top="data">
        <b-tr>
          <b-th colspan="9">header3</b-th>
        </b-tr>
      </template>
      <!-- We are using utility class `text-nowrap` to help illustrate horizontal scrolling -->
      <template #head(id)="scope">
        <div class="text-nowrap">Row ID</div>
      </template>
      <template #head()="scope">
        <div class="text-nowrap">
          Cols {{ scope.label }}
        </div>
      </template>
      <template #cell()="data">
      </template>
    </b-table>

    <b-table
      id="left-body"
      class="l_table l_left l_body"
      :sticky-header="stickyHeader"
      :no-border-collapse="noCollapse"
      :items="items"
      :fields="headFields"
      responsive
      style="overflow: auto"
      bordered
    >
      <!-- We are using utility class `text-nowrap` to help illustrate horizontal scrolling -->
      <template #thead-top="data">
        <b-tr>
          <b-th colspan="2">header1</b-th>
          <b-th colspan="2">header2</b-th>
        </b-tr>
      </template>
      <template #head(id)="scope">
        <div class="text-nowrap">Row ID</div>
      </template>
      <template #head()="scope">
        <div class="text-nowrap">
          {{ scope.label }}
        </div>
      </template>
    </b-table>
    <b-table
      id="right-body"
      class="l_table l_right l_body"
      :sticky-header="stickyHeader"
      :no-border-collapse="noCollapse"
      :items="items"
      :fields="tailFields"
      responsive
      style="overflow: auto"
      bordered
    >
      <!-- We are using utility class `text-nowrap` to help illustrate horizontal scrolling -->
      <template #thead-top="data">
        <b-tr>
          <b-th colspan="2">header1</b-th>
          <b-th colspan="2">header2</b-th>
        </b-tr>
      </template>
      <template #head(id)="scope">
        <div class="text-nowrap">Row ID</div>
      </template>
      <template #head()="scope">
        <div class="text-nowrap">
          Cols {{ scope.label }}
        </div>
      </template>
    </b-table>
  </div>
</template>
<script>
export default {
  name: 'VBSampleTable',
  data () {
    return {
      stickyHeader: true,
      noCollapse: false,
      fields: [
        { key: 'id', stickyColumn: false, isRowHeader: false },
        { key: 'a', stickyColumn: false, isRowHeader: false },
        { key: 'b', stickyColumn: false, isRowHeader: false },
        { key: 'c', stickyColumn: false, isRowHeader: false },
        { key: 'd', stickyColumn: false, isRowHeader: false },
        { key: 'e', stickyColumn: false, isRowHeader: false },
        { key: 'f', stickyColumn: false, isRowHeader: false },
        { key: 'g', stickyColumn: false, isRowHeader: false },
        { key: 'h', stickyColumn: false, isRowHeader: false },
        { key: 'i', stickyColumn: false, isRowHeader: false },
        { key: 'j', stickyColumn: false, isRowHeader: false },
        { key: 'k', stickyColumn: false, isRowHeader: false },
        { key: 'l', stickyColumn: false, isRowHeader: false },
      ],
      items: [
        { id: 1, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
        { id: 2, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
        { id: 3, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
        { id: 4, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
        { id: 5, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
        { id: 6, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
        { id: 7, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
        { id: 8, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
        { id: 9, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 },
        { id: 10, a: 0, b: 1, c: 2, d: 3, e: 4, f: 5, g: 6, h: 7, i: 8, j: 9, k: 10, l: 11 }
      ]
    }
  },
  computed: {
    headFields () {
      return this.fields.slice(0, 4)
    },
    tailFields () {
      return this.fields.slice(4)
    },
    headCols () {
      return this.items.slice(0, 4)
    },
    tailCols () {
      return this.items.slice(4)
    }
  },
  mounted () {
    const rh = document.querySelector('.l_table.l_right.l_header')
    const lh = document.querySelector('.l_table.l_left.l_header')
    const rb = document.querySelector('.l_table.l_right.l_body')
    const lb = document.querySelector('.l_table.l_left.l_body')
    rh.addEventListener('scroll', () => rb.scroll(rh.scrollLeft, 0))
    rb.addEventListener('scroll', () => rh.scroll(rb.scrollLeft, 0))
    rb.addEventListener('scroll', () => lb.scroll(0, rb.scrollTop))
    lb.addEventListener('scroll', () => rb.scroll(0, lb.scrollTop))
  }
}
</script>
<style>
.l_table::-webkit-scrollbar {
  display:none;
}
.l_table {
  -ms-overflow-style: none;
  margin-bottom: 0;
}
.l_table.l_header > table > tbody {
  visibility: collapse;
}
.l_table.l_body > table > thead {
  visibility: collapse;
}
</style>


Related Articles