Kyo
Kyo

Reputation: 23

How to keep sticky-header bootstrap table inside a div with dynamic data?

I am using bootstrap-table and dynamically adding my datas into the table (including headers)

I have checked below and other related posts but there's no luck.:

how-to-implement-fixed-header-for-table-in-bootstrap

And I tried out bootstrap-table's sticky-header extension which works when I'm scrolling the whole document, but when I want my table to be inside a div container, it's not working anymore.

My Codepen : example

Note: I placed data for examples, but in reality I am using ajax to call all the data, then initialize table after that, which is why I don't write anything inside the table in the html at all, and I need it to stay that way.

But after init, the header does not stick anymore.

I'm new to stackoverflow so I'm not sure if I'm doing this right, I couldn't make it into a fiddle but here's my code, thanks in advance.

$(document).ready(function () {
  var columns = [
    {
      field: "name",
      title: "Name"
    },
    {
      field: "age",
      title: "Age"
    },
    {
      field: "city",
      title: "City"
    }
  ];

  var data = [
    { name: "John Doe", age: 28, city: "New York" },
    { name: "Jane Smith", age: 34, city: "Los Angeles" },
    { name: "Jane Smith", age: 34, city: "Los Angeles" },
    { name: "Jane Smith", age: 34, city: "Los Angeles" },
    { name: "Jane Smith", age: 34, city: "Los Angeles" },
    { name: "Mike Johnson", age: 45, city: "Chicago" },
    { name: "Sarah Lee", age: 30, city: "Miami" }
  ];

  // init table
  $("#RealTable").bootstrapTable({
    data: data,
    columns: columns
  });
});
.divA {
  width: 100%;
  max-height: 200px; /* 設定 divA 高度為 50vh */
  overflow: auto; /* 允許內部內容捲動 */
  background-color: #e0e0e0;
  padding: 20px;
  position: relative; /* 需要這個來使 sticky 正常工作 */
}

/* 讓整個 table 設置 sticky */
#RealTable {
  position: relative;
  z-index: 1; /* 確保表格始終顯示 */
  border-collapse: separate; 
  border-spacing:0; 
  text-align:center;
}

.sticky-header th {
  position: sticky !important;
  top: 0;
  background-color: turquoise;
  color: white;
  z-index: 30 !important; /* 確保標題始終位於其他內容上方 */
}
.sticky-header th .th-inner {
  position: sticky !important;
  top: 0;
}

th,
td {
  padding: 10px;
  border: 1px solid #ddd;
  text-align: center;
}

.content {
  padding: 0px 0px 50px 0px;
}

.table {
  width: 100%;
  border: 1px solid #ddd;
  text-align: center;
}
<html lang="zh-Hant">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Sticky Header with Bootstrap Table</title>

  <!-- 引入 Bootstrap CSS -->
  <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">

  <!-- 引入 bootstrap-table 的 CSS -->
  <link href="https://unpkg.com/bootstrap-table/dist/bootstrap-table.min.css" rel="stylesheet">
</head>

<body>
  <div class="section">
    <h1>title</h1>
    <p>qweqwewq</p>
  </div>
  <div class="divA">
    <div class="row table-responsive">
      <table id="RealTable" class="table table-hover text-nowrap">
        <thead class="sticky-header">
        </thead>
        <tbody>
          <!-- dynamic added -->
        </tbody>
      </table>
    </div>
  </div>

  <div class="section">
    <h1>title2</h1>
    <p>qweqwewq</p>
    <p>qweqwewq</p>
    <p>qweqwewq</p>
  </div>

  <!--  jQuery -->
  <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

  <!--  Bootstrap JS -->
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js"></script>

  <!--  bootstrap-table 的 JS -->
  <script src="https://unpkg.com/bootstrap-table/dist/bootstrap-table.min.js"></script>

</body>

</html>

Current work (non-sticky header):

enter image description here

Desirder result I want (sticky header inside table):

enter image description here

Upvotes: 1

Views: 78

Answers (2)

Kyo
Kyo

Reputation: 23

update: I fixed the page with the other answer's help, now it's working like @Raghavendra' s answer, for anyone who's also troubled by sticky-header like me. I decided to use my custom-css instead of the Bootstrap table extension.

$(document).ready(function () {
  var columns = [
    {
      field: "name",
      title: "Name"
    },
    {
      field: "age",
      title: "Age"
    },
    {
      field: "city",
      title: "City"
    }
  ];

  var data = [
    { name: "John Doe", age: 28, city: "New York" },
    { name: "Jane Smith", age: 34, city: "Los Angeles" },
    { name: "Jane Smith2", age: 31, city: "Los Angeles" },
    { name: "Jane Smith3", age: 32, city: "Los Angeles" },
    { name: "Jane Smith4", age: 33, city: "Los Angeles" },
    { name: "Mike Johnson", age: 45, city: "Chicago" },
    { name: "Sarah Lee", age: 30, city: "Miami" }
  ];

  // init table
  $("#RealTable").bootstrapTable({
    data: data,
    columns: columns
  });
});
.divA {
  width: 100%;
  max-height: 50vh; /* set height = 50vh */
  overflow: auto; /* allow scrolling in divA */
  padding: 20px;
  padding-top: 0;
  position: relative; /* need this for sticky to work */
}
/* it was these bootstrap classes*/
.table-responsive {
    overflow-x: initial !important;
}

.bootstrap-table .fixed-table-container .fixed-table-body {
    overflow: initial !important;
}

.custom-sticky-header th {
  position: sticky !important;
  top: 0;
  background-color: turquoise;
  color: white;
  z-index: 30 !important; /* make sure it's on the top of other things */
}

th,
td {
  padding: 10px;
  border: 1px solid #ddd;
  text-align: center;
}
<html lang="zh-Hant">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Sticky Header with Bootstrap Table</title>

  <!-- 引入 Bootstrap CSS -->
  <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">

  <!-- 引入 bootstrap-table 的 CSS -->
  <link href="https://unpkg.com/bootstrap-table/dist/bootstrap-table.min.css" rel="stylesheet">
</head>

<body>
  <div class="section">
    <h1>title</h1>
    <p>qweqwewq</p>
  </div>
  <div class="divA">
    <div class="row table-responsive">
      <table id="RealTable" class="table table-hover text-nowrap">
        <thead class="custom-sticky-header">
        </thead>
        <tbody>
          <!-- dynamic added -->
        </tbody>
      </table>
    </div>
  </div>

  <div class="section">
    <h1>title2</h1>
    <p>qweqwewq</p>
    <p>qweqwewq</p>
    <p>qweqwewq</p>
  </div>

  <!--  jQuery -->
  <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

  <!--  Bootstrap JS -->
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js"></script>

  <!--  bootstrap-table 的 JS -->
  <script src="https://unpkg.com/bootstrap-table/dist/bootstrap-table.min.js"></script>

</body>

</html>

Upvotes: 1

Raghavendra N
Raghavendra N

Reputation: 5496

Going through some of the comments in this question, I figured out that position sticky doesn't work if any of the parent elements has property like overflow: hidden or overflow: auto.

In your case also it is the same issue. So adding the below css rules will solve your issue.

.table-responsive {
  overflow-x: initial !important;
  margin-top: 20px;
}

.bootstrap-table .fixed-table-container .fixed-table-body {
  overflow: initial !important;
}

/* Added this extra style, otherwise scrolled content appears above the header */
.divA {
  padding-top: 0;
}

Please check this working snippet:

$(document).ready(function () {
  var columns = [
    {
      field: "name",
      title: "Name"
    },
    {
      field: "age",
      title: "Age"
    },
    {
      field: "city",
      title: "City"
    }
  ];

  var data = [
    { name: "John Doe", age: 28, city: "New York" },
    { name: "Jane Smith", age: 34, city: "Los Angeles" },
    { name: "Jane Smith", age: 34, city: "Los Angeles" },
    { name: "Jane Smith", age: 34, city: "Los Angeles" },
    { name: "Jane Smith", age: 34, city: "Los Angeles" },
    { name: "Mike Johnson", age: 45, city: "Chicago" },
    { name: "Sarah Lee", age: 30, city: "Miami" }
  ];

  // init table
  $("#RealTable").bootstrapTable({
    data: data,
    columns: columns
  });
});
.divA {
  width: 100%;
  max-height: 300px; /* 設定 divA 高度為 50vh */
  overflow: auto; /* 允許內部內容捲動 */
  background-color: #e0e0e0;
  padding: 20px;
  padding-top: 0;
  position: relative; /* 需要這個來使 sticky 正常工作 */
}

.table-responsive {
  overflow-x: initial !important;
  margin-top: 20px;
}

.bootstrap-table .fixed-table-container .fixed-table-body {
  overflow: initial !important;
}

/* 讓整個 table 設置 sticky */
#RealTable {
  position: relative;
  z-index: 1; /* 確保表格始終顯示 */
  border-collapse: separate; 
  border-spacing:0; 
  text-align:center;
}

.sticky-header th {
  position: sticky !important;
  top: 0;
  background-color: turquoise;
  color: white;
  z-index: 30 !important; /* 確保標題始終位於其他內容上方 */
}
.sticky-header th .th-inner {
  position: sticky !important;
  top: 0;
}

th,
td {
  padding: 10px;
  border: 1px solid #ddd;
  text-align: center;
}

.content {
  padding: 0px 0px 50px 0px;
}

.table {
  width: 100%;
  border: 1px solid #ddd;
  text-align: center;
}
<html lang="zh-Hant">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Sticky Header with Bootstrap Table</title>

  <!-- 引入 Bootstrap CSS -->
  <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">

  <!-- 引入 bootstrap-table 的 CSS -->
  <link href="https://unpkg.com/bootstrap-table/dist/bootstrap-table.min.css" rel="stylesheet">
</head>

<body>
  <div class="section">
    <h1>title</h1>
    <p>qweqwewq</p>
  </div>
  <div class="divA">
    <div class="row table-responsive">
      <table id="RealTable" class="table table-hover text-nowrap">
        <thead class="sticky-header">
        </thead>
        <tbody>
          <!-- dynamic added -->
        </tbody>
      </table>
    </div>
  </div>

  <div class="section">
    <h1>title2</h1>
    <p>qweqwewq</p>
    <p>qweqwewq</p>
    <p>qweqwewq</p>
  </div>

  <!--  jQuery -->
  <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>

  <!--  Bootstrap JS -->
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.bundle.min.js"></script>

  <!--  bootstrap-table 的 JS -->
  <script src="https://unpkg.com/bootstrap-table/dist/bootstrap-table.min.js"></script>

</body>

</html>

Upvotes: 1

Related Questions