├── .gitignore ├── LICENSE ├── README.md ├── angu-fixed-header-table.js ├── bower.json ├── demo ├── demo.html └── demo.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | bower_components/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Jason Watmore 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | angu-fixed-header-table 2 | ======================= 3 | 4 | An AngularJS fixed header scrollable table directive 5 | 6 | ### Demo 7 | 8 | To see a demo and further details go to http://pointblankdevelopment.com.au/blog/angularjs-fixed-header-scrollable-table-directive 9 | 10 | ### Installation 11 | 12 | #### NPM 13 | 14 | `npm install angu-fixed-header-table` 15 | 16 | #### Bower 17 | 18 | `bower install angu-fixed-header-table` 19 | 20 | Alternatively download the code and include the angu-fixed-header-table.js file in your page. 21 | 22 | ### Integration with your AngularJS app 23 | 24 | Add the 'anguFixedHeaderTable' directive as a dependency of your AngularJS application: 25 | 26 | ```javascript 27 | angular.module('myApp', ['anguFixedHeaderTable']); 28 | ``` 29 | 30 | ### Usage 31 | 32 | Simply add the *fixed-header* attribute to any tables you'd like to have a fixed header: 33 | 34 | ```html 35 | 36 | ... 37 |
38 | ``` 39 | 40 | The table height can be set using CSS on the table element or by adding a *table-height* attribute to the table element eg: table-height="500px". 41 | -------------------------------------------------------------------------------- /angu-fixed-header-table.js: -------------------------------------------------------------------------------- 1 | /** 2 | * AngularJS fixed header scrollable table directive 3 | * @author Jason Watmore (http://jasonwatmore.com) 4 | * @version 1.2.0 5 | */ 6 | (function () { 7 | angular 8 | .module('anguFixedHeaderTable', []) 9 | .directive('fixedHeader', fixedHeader); 10 | 11 | fixedHeader.$inject = ['$timeout']; 12 | 13 | function fixedHeader($timeout) { 14 | return { 15 | restrict: 'A', 16 | link: link 17 | }; 18 | 19 | function link($scope, $elem, $attrs, $ctrl) { 20 | var elem = $elem[0]; 21 | 22 | // wait for data to load and then transform the table 23 | $scope.$watch(tableDataLoaded, function(isTableDataLoaded) { 24 | if (isTableDataLoaded) { 25 | transformTable(); 26 | } 27 | }); 28 | 29 | function tableDataLoaded() { 30 | // first cell in the tbody exists when data is loaded but doesn't have a width 31 | // until after the table is transformed 32 | var firstCell = elem.querySelector('tbody tr:first-child td:first-child'); 33 | return firstCell && !firstCell.style.width; 34 | } 35 | 36 | function transformTable() { 37 | // reset display styles so column widths are correct when measured below 38 | angular.element(elem.querySelectorAll('thead, tbody, tfoot')).css('display', ''); 39 | 40 | // wrap in $timeout to give table a chance to finish rendering 41 | $timeout(function () { 42 | // set widths of columns 43 | angular.forEach(elem.querySelectorAll('tr:first-child th'), function (thElem, i) { 44 | 45 | var tdElems = elem.querySelector('tbody tr:first-child td:nth-child(' + (i + 1) + ')'); 46 | var tfElems = elem.querySelector('tfoot tr:first-child td:nth-child(' + (i + 1) + ')'); 47 | 48 | var columnWidth = tdElems ? tdElems.offsetWidth : thElem.offsetWidth; 49 | if (tdElems) { 50 | tdElems.style.width = columnWidth + 'px'; 51 | } 52 | if (thElem) { 53 | thElem.style.width = columnWidth + 'px'; 54 | } 55 | if (tfElems) { 56 | tfElems.style.width = columnWidth + 'px'; 57 | } 58 | }); 59 | 60 | // set css styles on thead and tbody 61 | angular.element(elem.querySelectorAll('thead, tfoot')).css('display', 'block'); 62 | 63 | angular.element(elem.querySelectorAll('tbody')).css({ 64 | 'display': 'block', 65 | 'height': $attrs.tableHeight || 'inherit', 66 | 'overflow': 'auto' 67 | }); 68 | 69 | // reduce width of last column by width of scrollbar 70 | var tbody = elem.querySelector('tbody'); 71 | var scrollBarWidth = tbody.offsetWidth - tbody.clientWidth; 72 | if (scrollBarWidth > 0) { 73 | // for some reason trimming the width by 2px lines everything up better 74 | scrollBarWidth -= 2; 75 | var lastColumn = elem.querySelector('tbody tr:first-child td:last-child'); 76 | lastColumn.style.width = (lastColumn.offsetWidth - scrollBarWidth) + 'px'; 77 | } 78 | }); 79 | } 80 | } 81 | } 82 | })(); -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angu-fixed-header-table", 3 | "version": "1.2.0", 4 | "authors": [ 5 | "Jason Watmore (http://jasonwatmore.com)", 6 | "Jean Maynier" 7 | ], 8 | "description": "AngularJS fixed header scrollable table directive", 9 | "main": "angu-fixed-header-table.js", 10 | "keywords": [ 11 | "AngularJS", 12 | "Fixed Header Table" 13 | ], 14 | "license": "MIT", 15 | "homepage": "http://pointblankdevelopment.com.au/blog/angularjs-fixed-header-scrollable-table-directive", 16 | "ignore": [ 17 | "**/.*", 18 | "node_modules", 19 | "bower_components", 20 | "test", 21 | "tests" 22 | ], 23 | "dependencies": { 24 | "angular": ">=1.2.16" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /demo/demo.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | AngularJS Fixed Header Scrollable Table 7 | 8 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
Header 1Header 2Header 3Header 4
Row {{item}} Col 1Row {{item}} Col 2Row {{item}} Col 3Row {{item}} Col 4
Footer 1Footer 2Footer 3Footer 4
42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /demo/demo.js: -------------------------------------------------------------------------------- 1 | angular.module('myApp', ['anguFixedHeaderTable']); -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angu-fixed-header-table", 3 | "description": "AngularJS fixed header scrollable table directive", 4 | "version": "1.2.3", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/cornflourblue/angu-fixed-header-table.git" 8 | }, 9 | "license": "MIT", 10 | "homepage": "https://pointblankdevelopment.com.au/blog/angularjs-fixed-header-scrollable-table-directive", 11 | "author": { 12 | "name": "Jason Watmore", 13 | "url": "http://jasonwatmore.com" 14 | }, 15 | "keywords": [ 16 | "AngularJS", 17 | "Fixed Header Table" 18 | ], 19 | "dependencies": { 20 | "angular": "^1.2.16" 21 | } 22 | } 23 | --------------------------------------------------------------------------------