Ensure that the table header remains in place while scrolling within a fixed height constraint

I am experiencing a repeated <tbody> element in my bootstrap table with a fixed height of 140px, and I have implemented scrolling if the data exceeds that height.

I am encountering challenges in keeping the header with values 'Season 2018 2019 2020 2021' fixed when scrolling the table. Has anyone else encountered a similar issue?

angular.module('plunker', []);

angular.module('plunker').controller('MyCtrl', ['$scope', function($scope) {
    $scope.data = {
        'widget1': {
            '1': 10,
            '2': 5
        },
        'widget2': {
            '4': 7,
            '6': 6
        }
    };
    
    $scope.seasons=[{
      'season':'Winter',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Autumn',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Rainy',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Summer',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Spring',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Windy',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    }]
}]);
.table-scroll-header-fix { 
    width:238px;
    overflow-y: auto;
    max-height: 140px;
}
<!DOCTYPE html>
<html ng-app="plunker">
  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
    <script src="app.js"></script>
  </head>
  <body>
<div class="table-scroll-header-fix" ng-controller="MyCtrl">
<table class="table  table-responsive">
    <thead>
        <tr class="summary-table-header">
             <th>Season</th>
            <th>2018</th>
            <th>2019</th>
            <th>2020 </th>
            <th>2021 </th>
         </tr>
    </thead>
    <tbody ng-repeat="item in seasons">
        <tr style="cursor:pointer">
            <td>{{item.season}}</td>
            <td>{{item.2017}}</td>
            <td>{{item.2018}}</td>
            <td>{{item.2019}}</td>
            <td>{{item.2020}}</td>
        </tr>
    </tbody>
   </table>
    </div>
  </body>
</html>

Answer №1

Confirm if this meets your requirements. I'll provide a detailed explanation.

angular.module('plunker', []);

angular.module('plunker').controller('MyCtrl', ['$scope', function($scope) {
  $scope.data = {
    'widget1': {
      '1': 10,
      '2': 5
    },
    'widget2': {
      '4': 7,
      '6': 6
    }
  };

  $scope.seasons = [{
      'season': 'Winter',
      '2018': 3,
      '2019': 34,
      '2020': 43,
      '2021': 4,
    },
    {
      'season': 'Autumn',
      '2018': 3,
      '2019': 34,
      '2020': 43,
      '2021': 4,
    },
    {
      'season': 'Rainy',
      '2018': 3,
      '2019': 34,
      '2020': 43,
      '2021': 4,
    },
    {
      'season': 'Summer',
      '2018': 3,
      '2019': 34,
      '2020': 43,
      '2021': 4,
    },
    {
      'season': 'Spring',
      '2018': 3,
      '2019': 34,
      '2020': 43,
      '2021': 4,
    },
    {
      'season': 'Windy',
      '2018': 3,
      '2019': 34,
      '2020': 43,
      '2021': 4,
    }
  ]
}]);
.table-wrapper {
  position: relative;
}

.table-scroll-header-fix {
  /*width:238px;*/
  overflow-y: auto;
  max-height: 120px;
}

.table-responsive {
  width: 100%;
}

.table-responsive.tablex>thead {
  position: absolute;
  top: 0;
  background: #ffca68;
}

.table-responsive.tablex>thead>tr>th,
.table-responsive.tablex>tbody>tr>td{
  width: 200px;
}
.table-responsive.tablex>thead>tr>th:first-child,
.table-responsive.tablex>tbody>tr>td:first-child{
  width: 320px;
}

.table-responsive th {
  text-align: left;
}
<!DOCTYPE html>
<html ng-app="plunker">

<head>
  <meta charset="utf-8" />
  <title>AngularJS Plunker</title>
  <script>
    document.write('<base href="' + document.location + '" />');
  </script>
  <link rel="stylesheet" href="style.css" />
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
  <script src="app.js"></script>
</head>

<body>
  <div class="table-wrapper">
    <div class="table-scroll-header-fix" ng-controller="MyCtrl">
      <table class="table  table-responsive tablex">
        <thead>
          <tr class="summary-table-header">
            <th>Season</th>
            <th>2018</th>
            <th>2019</th>
            <th>2020 </th>
            <th>2021 </th>
          </tr>
        </thead>
        <tbody><tr><td>&nbsp;</td></tr></tbody>
        <tbody ng-repeat="item in seasons">
          <tr style="cursor:pointer">
            <td>{{item.season}}</td>
            <td>{{item.2018}}</td>
            <td>{{item.2019}}</td>
            <td>{{item.2020}}</td>
            <td>{{item.2021}}</td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</body>

<html>

Answer №2

Based on your inquiry, it seems you are looking for a way to have a fixed table header with scrolling in the body.

To achieve this functionality, we can set the overflow property to the table body instead of the container as demonstrated below.

angular.module('plunker', []);

angular.module('plunker').controller('MyCtrl', ['$scope', function($scope) {
    $scope.data = {
        'widget1': {
            '1': 10,
            '2': 5
        },
        'widget2': {
            '4': 7,
            '6': 6
        }
    };
    
    $scope.seasons=[{
      'season':'Winter',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Autumn',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Rainy',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Summer',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Spring',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Windy',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    }]
}]);
.table-scroll-header-fix tbody {
    display:block;
    height:100px;
    overflow:auto;
}
.table-scroll-header-fix thead, tbody tr {
    display:table;
    width:100%;
    table-layout:fixed;
}
.table-scroll-header-fix thead {
    width: calc( 100% - 1em )
}
.table-scroll-header-fix table {
    width:238px;
}
<!DOCTYPE html>
<html ng-app="plunker">
  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
    <script src="app.js"></script>
  </head>
  <body>
<div class="table-scroll-header-fix" ng-controller="MyCtrl">
<table class="table  table-responsive table-fixed">
    <thead>
        <tr class="summary-table-header">
             <th>Season</th>
            <th>2018</th>
            <th>2019</th>
            <th>2020 </th>
            <th>2021 </th>
         </tr>
    </thead>
    <tbody >
        <tr style="cursor:pointer" ng-repeat="item in seasons">
            <td>{{item.season}}</td>
            <td>{{item.2017}}</td>
            <td>{{item.2018}}</td>
            <td>{{item.2019}}</td>
            <td>{{item.2020}}</td>
        </tr>
    </tbody>
   </table>
    </div>
  </body>
</html>

Answer №3

I encountered some challenges with this issue for a considerable amount of time. I stumbled upon a code snippet related to tables, although the exact source eludes me.
Feel free to take a look at this Plunker as an example.
Please let me know if this solution does not meet your needs.

Answer №4

To resolve the issue, simply apply the CSS property position: fixed; to the

<tr class="summary-table-header">
. Additionally, consider adding a background color to prevent text overlap.

angular.module('plunker', []);

angular.module('plunker').controller('MyCtrl', ['$scope', function($scope) {
    $scope.data = {
        'widget1': {
            '1': 10,
            '2': 5
        },
        'widget2': {
            '4': 7,
            '6': 6
        }
    };
    
    $scope.seasons=[{
      'season':'Winter',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Autumn',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Rainy',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Summer',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Spring',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Windy',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    }]
}]);
.table-scroll-header-fix { 
    width:238px;
    overflow-y: auto;
    max-height: 140px;
}

.summary-table-header {
position: fixed;
background-color: #fff;
}
<!DOCTYPE html>
<html ng-app="plunker">
  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
    <script src="app.js"></script>
  </head>
  <body>
<div class="table-scroll-header-fix" ng-controller="MyCtrl">
<table class="table  table-responsive">
    <thead>
        <tr class="summary-table-header">
             <th>Season</th>
            <th>2018</th>
            <th>2019</th>
            <th>2020 </th>
            <th>2021 </th>
         </tr>
    </thead>
    <tbody ng-repeat="item in seasons">
        <tr style="cursor:pointer">
            <td>{{item.season}}</td>
            <td>{{item.2017}}</td>
            <td>{{item.2018}}</td>
            <td>{{item.2019}}</td>
            <td>{{item.2020}}</td>
        </tr>
    </tbody>
   </table>
    </div>
  </body>
</html>

Answer №5

angular.module('app', []);

angular.module('app').controller('DataController', ['$scope', function($scope) {
    $scope.data = {
        'widget1': {
            '1': 10,
            '2': 5
        },
        'widget2': {
            '4': 7,
            '6': 6
        }
    };
    
    $scope.seasons=[{
      'season':'Winter',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Autumn',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Rainy',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Summer',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Spring',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    },
    {
      'season':'Windy',
      '2018':3,
      '2019':34,
      '2020':43,
      '2021':4,
    }]
}]);
.fixed_headers {
  width: 500px;
  table-layout: fixed;
  border-collapse: collapse;
}
.fixed_headers th {
  text-decoration: underline;
}
.fixed_headers th,
.fixed_headers td {
  padding: 5px;
  text-align: left;
}
.fixed_headers td:nth-child(1),
.fixed_headers th:nth-child(1) {
  min-width: 100px;
}
.fixed_headers td:nth-child(2),
.fixed_headers th:nth-child(2) {
  min-width: 100px;
}
.fixed_headers td:nth-child(3),
.fixed_headers th:nth-child(3) {
  width: 100px;
}
.fixed_headers td:nth-child(4),
.fixed_headers th:nth-child(4) {
  width: 100px;
}
.fixed_headers td:nth-child(5),
.fixed_headers th:nth-child(5) {
  width: 100px;
}
.fixed_headers thead {
  background-color: #333;
  color: #FDFDFD;
}
.fixed_headers thead tr {
  display: block;
  position: relative;
}
.fixed_headers tbody {
  display: block;
  overflow: auto;
  width: 100%;
  height: 150px;
}
.fixed_headers tbody tr:nth-child(even) {
  background-color: #DDD;
}
 

 
<!DOCTYPE html>
<html ng-app="app">
  <head>
    <meta charset="utf-8" />
    <title>AngularJS App</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
    <script src="app.js"></script>
  </head>
  <body>
<div class="table-scroll-header-fix" ng-controller="DataController">
<table class="table table-responsive fixed_headers">
    <thead>
        <tr class="summary-table-header">
            <th>Season</th>
            <th>2018</th>
            <th>2019</th>
            <th>2020</th>
            <th>2021</th>
         </tr>
    </thead>
    <tbody>
        <tr ng-repeat="item in seasons" style="cursor:pointer">
            <td>{{item.season}}</td>
            <td>{{item.2018}}</td>
            <td>{{item.2019}}</td>
            <td>{{item.2020}}</td>
            <td>{{item.2021}}</td>
        </tr>
    </tbody>
   </table>
    </div>
  </body>
</html>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using JQuery to trigger the onchange event for a select tag

I am working with jQuery where I need to append select tags inside a table for each row. I want to add an onChange event for each dropdown on every row. However, the approach I have taken doesn't seem to be working. This is what my jQuery code looks l ...

Add the onclick function to $(document).ready for applying the desired functionality

I've been trying to create a fading effect for 3 divs on my page, similar to the one in this example: http://jsfiddle.net/x4qjscgv/6/ However, I want the fade animation to trigger only when a user clicks a button. I attempted to use the document.getE ...

Is it possible to use AngularDart's ng-repeat directive in HTML tables

I've been struggling to iterate over lists with sublists and display them as <tr> elements without much luck. The following code represents what I'm trying to achieve: <table> <tr> <th>1</th> <th>2& ...

secured angular service or controller

In my Angular module, I have created some services that are meant to be used only by other services within the same module. While I want to expose them for testing purposes, I do not want these services to be accessible by other modules. Is there a way to ...

Is it possible to maintain a div's height in proportion to its width using CSS?

Is it possible to set a CSS variable so that my div's height is always half of its width, and the width scales with the screen size (in percentage)? <div class="ss"></div> CSS: .ss { width: 30%; height: 50% of the width; } This ...

Refreshing material ui select choices based on user input

Just getting started with Reactjs and I need some help. I have a material ui select element that has default values set, and when I click the 'ADD USER' button and submit, I can add new values to the select element. I'm also able to delete o ...

Trying to focus on an input within a span element is not functional

Encountered a puzzling issue where changing the color of a label when the input field is in focus is easy, except when the input is wrapped within a span. Pulling my hair out trying to figure this one. Any insights? Visit Codepen <div class="input_con ...

triggering e.stopImmediatePropagation() within an onclick event handler

Is there a way to retrieve the event object from an onclick attribute? I attempted the following: <a href="something.html" onclick="function(e){e.stopImmediatePropagation();}">Click me</a> In addition, I tried this: <a href="something.ht ...

How can I stop the accordion from toggling in Bootstrap V5 when clicking on an element in the header?

In the latest version of Bootstrap, v5, it seems that using e.stopPropagation(); no longer prevents the accordion from toggling when an element in the header is clicked. Do you have a solution for this problem? How to prevent accordion from toggling when ...

Creating immersive experiences with fabric.js in fullscreen mode on canvas

Attempting to implement a fullscreen mode (using HTML5 fullscreen) for a canvas object created with Fabric.js. var canvas = fabricCanvas.getSelectionElement(); if(canvas.requestFullScreen) { canvas.requestFullScreen(); } else if(canvas.webkitRequestFu ...

Illustration next to content featuring a heading and a paragraph

I've been working on a website design and trying to position text next to an image. It seems like a simple task, but I'm struggling to make it work. Here's an illustration of how I want the layout to look: So far, here is the HTML code I&a ...

Tips for making a JavaFX Button transparent without reducing the hitbox size

When I create a new Button in JavaFX and make the background transparent using either myButton.setBackground(Background.EMPTY); or myButton.setStyle("-fx-background-color: transparent;"), the hitbox is reduced to just the text inside the button when trigge ...

What is the best way to apply box-shadow specifically to the bottom of a div element using css?

I'm looking to apply a box-shadow to only the bottom of a div element using CSS. The desired effect is shown in the image below: https://i.sstatic.net/L2vK4.png I want to achieve the red line indicated in the picture above. Here's my current co ...

Issue with Phonegap app not automatically adjusting to fill entire viewport height at start

I am encountering an issue with testing a PhoneGap application on my Samsung Galaxy smartphone. Upon initial load, the body does not completely fill 100% of the viewport's height (please refer to the screenshot attached.) This occurrence is independe ...

Elements shifting positions based on the size of the window

I am facing an issue with positioning the register form on my website. I want it to be fixed at the bottom-right corner of the window, without reaching the top. Although I managed to achieve this, the problem arises when the screen resolution changes. For ...

Adding a fresh, spacious breakpoint in Bootstrap 4 with just CSS

I encountered an issue when the extra large Bootsrap 4 max container width, set at 1140px, was not wide enough for my needs. I aim to ensure that my websites look good on large monitors as well, but the bootstrap grid is too narrow. The most straightforwar ...

Retrieve the numerical key within an md-directive

How can I access a Json object with a numerical key in an ng directive? Take a look at the object below: { 0 : { value : { firstname : "John" , lastname : "Doe" } } I want to retrieve the first name of this object using a md directive like: <th md-c ...

How can absolute path static images be served in a Node.js server with Angular 10 img tag?

I've been looking for a solution here without any luck, so I'm reaching out for help. How can I properly serve my static images that are located in the nodejs server: public/img Here's how I have set it up in Node.js (before app.listen( ...

Refreshing the browser causes the URL to be updated due to the utilization of $routeProvider for client-side routing

Currently, I am developing a single-page application using Angular for the client-side and Nodejs (Express) for the server-side. To manage different views and browser history, I am utilizing $routeProvider in Angular. While everything works smoothly withou ...

Incorporate npm libraries into vanilla JavaScript for HTML pages

Attempting to incorporate an npm package into plain JS/HTML served using Python and Flask. <script type="module"> import { configureChains, createClient } from "./node_modules/@wagmi/core"; import { bsc } from "./nod ...