0

I am trying to make a table on my angular page with fixed headers and footers.

<table class="table table-bordered table-striped table-hover" fixed-header>
  <thead>
      <tr>
          <th>Name</th>
          <th>Amount</th>
          <th>Id</th>
      </tr>
  </thead>
  <tbody>
      <tr class="info" ng-repeat="item in ctrl.items track by $index">
          <td>
              <input type="checkbox"/>
              <a>{{item.displayName}}</a>
          </td>
          <td>
              {{item.marketValue}}
          </td>
          <td>
              {{item.positions}}
          </td>
      </tr>
  </tbody>
  <tfoot>
      <tr>
          <td>Name</td>
          <td>Amount</td>
          <td>Id</td>
      </tr>
  </tfoot>
</table>

I have a demo of my angular table here on plunker. I'm using the angu-fixed-header-table plugin but the table refuses to have fixed headers. Any ideas on how to fix it?

1
  • I have a demo of my angular table here on plunker. Only Hello World! Commented Apr 19, 2016 at 5:08

1 Answer 1

1

I think you are missing to add table-height="". Here is the working demo. https://plnkr.co/edit/BdiQzYxVyPdFXU9TI44t?p=preview

/**
 * AngularJS fixed header scrollable table directive
 * @author Jason Watmore <[email protected]> (http://jasonwatmore.com)
 * @version 1.2.0
 */
(function () {
    angular
        .module('anguFixedHeaderTable', [])
        .directive('fixedHeader', fixedHeader);

    fixedHeader.$inject = ['$timeout'];

    function fixedHeader($timeout) {
        return {
            restrict: 'A',
            link: link
        };

        function link($scope, $elem, $attrs, $ctrl) {
            var elem = $elem[0];

            // wait for data to load and then transform the table
            $scope.$watch(tableDataLoaded, function(isTableDataLoaded) {
                if (isTableDataLoaded) {
                    transformTable();
                }
            });

            function tableDataLoaded() {
                // first cell in the tbody exists when data is loaded but doesn't have a width
                // until after the table is transformed
                var firstCell = elem.querySelector('tbody tr:first-child td:first-child');
                return firstCell && !firstCell.style.width;
            }

            function transformTable() {
                // reset display styles so column widths are correct when measured below
                angular.element(elem.querySelectorAll('thead, tbody, tfoot')).css('display', '');

                // wrap in $timeout to give table a chance to finish rendering
                $timeout(function () {
                    // set widths of columns
                    angular.forEach(elem.querySelectorAll('tr:first-child th'), function (thElem, i) {

                        var tdElems = elem.querySelector('tbody tr:first-child td:nth-child(' + (i + 1) + ')');
                        var tfElems = elem.querySelector('tfoot tr:first-child td:nth-child(' + (i + 1) + ')');

                        var columnWidth = tdElems ? tdElems.offsetWidth : thElem.offsetWidth;
                        if (tdElems) {
                            tdElems.style.width = columnWidth + 'px';
                        }
                        if (thElem) {
                            thElem.style.width = columnWidth + 'px';
                        }
                        if (tfElems) {
                            tfElems.style.width = columnWidth + 'px';
                        }
                    });

                    // set css styles on thead and tbody
                    angular.element(elem.querySelectorAll('thead, tfoot')).css('display', 'block');

                    angular.element(elem.querySelectorAll('tbody')).css({
                        'display': 'block',
                        'height': $attrs.tableHeight || 'inherit',
                        'overflow': 'auto'
                    });

                    // reduce width of last column by width of scrollbar
                    var tbody = elem.querySelector('tbody');
                    var scrollBarWidth = tbody.offsetWidth - tbody.clientWidth;
                    if (scrollBarWidth > 0) {
                        // for some reason trimming the width by 2px lines everything up better
                        scrollBarWidth -= 2;
                        var lastColumn = elem.querySelector('tbody tr:first-child td:last-child');
                        lastColumn.style.width = (lastColumn.offsetWidth - scrollBarWidth) + 'px';
                    }
                });
            }
        }
    }
})();

var app = angular.module('myApp', ['anguFixedHeaderTable'])
.controller('DemoController', function($scope) {
    $scope.products = [
      {
        displayName: 'Prod1',
        marketValue: '100',
        positions:'1'
      },
      {
        displayName: 'Prod1',
        marketValue: '100',
        positions:'1'
      },
      {
        displayName: 'Prod1',
        marketValue: '100',
        positions:'1'
      },
      {
        displayName: 'Prod1',
        marketValue: '100',
        positions:'1'
      },
      {
        displayName: 'Prod1',
        marketValue: '100',
        positions:'1'
      },
      {
        displayName: 'Prod1',
        marketValue: '100',
        positions:'1'
      },
      {
        displayName: 'Prod1',
        marketValue: '100',
        positions:'1'
      },
      {
        displayName: 'Prod1',
        marketValue: '100',
        positions:'1'
      },
      {
        displayName: 'Prod1',
        marketValue: '100',
        positions:'1'
      },
      {
        displayName: 'Prod1',
        marketValue: '100',
        positions:'1'
      },
      {
        displayName: 'Prod1',
        marketValue: '100',
        positions:'1'
      },
      {
        displayName: 'Prod1',
        marketValue: '100',
        positions:'1'
      },
      {
        displayName: 'Prod1',
        marketValue: '100',
        positions:'1'
      },
      {
        displayName: 'Prod1',
        marketValue: '100',
        positions:'1'
      },
    ];
});
<!DOCTYPE html>
<html ng-app="myApp">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="[email protected]" src="https://code.angularjs.org/1.4.9/angular.js" data-semver="1.4.9"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="DemoController">
<table table-height="100px" class="table table-bordered table-striped table-hover" fixed-header>
  <thead>
      <tr>
          <th>Name</th>
          <th>Amount</th>
          <th>Id</th>
      </tr>
  </thead>
  <tbody>
      <tr class="info" ng-repeat="item in products track by $index">
          <td>
              <input type="checkbox"/>
              <a>{{item.displayName}}</a>
          </td>
          <td>
              {{item.marketValue}}
          </td>
          <td>
              {{item.positions}}
          </td>
      </tr>
  </tbody>
  <tfoot>
      <tr>
          <td>Name</td>
          <td>Amount</td>
          <td>Id</td>
      </tr>
  </tfoot>
</table>
  </body>

</html>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.