[转]AngularJS fixed header scrollable table directive
本文转自:http://pointblankdevelopment.com.au/blog/angularjs-fixed-header-scrollable-table-directive
This post contains a custom AngularJS directive you can use to give your html table a fixed header and footer with a scrollable body, we developed it for a law firm marketing website recently, it uses a pure CSS approach and doesn't touch any of the html tags, leaving the html table completely intact and happily semantic :)
Creating a fixed header scrollable table using purely CSS turns out to be a surprisingly tricky thing to do, in an ideal world I thought it would just be a matter of setting the height of the table body and "overflow:hidden", but there turns out to be a bit more to it than that, especially if you have a table that contains dynamic content because the width of each column in the thead and tbody need to be set in order for it to continue looking like a table and not just a big mess.
In a nutshell the CSS changes that need to happen are:
- Set the width of each column in the thead and tbody, making sure they match up so the columns aren't wonky
- Set the thead and tbody to "display:block;"
- Set the tbody height and "overflow:auto;" to add the scrollbar
- When there's a scrollbar (when the tbody content overflows it's height), reduce the width of the final column in the tbody by the width of the scrollbar
Here's the solution I came up with:
- Install using Bower:
bower install angu-fixed-header-table - See on Plunker at http://plnkr.co/edit/YIohJ7?p=preview)
- Available on GitHub at https://github.com/cornflourblue/angu-fixed-header-table
The fixedHeader AngularJS directive
|
1
2
3
4
5
6
7
8
9
10
11
12
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
/** * AngularJS fixed header scrollable table directive * @author Jason Watmore <jason@pointblankdevelopment.com.au> (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'; } }); } } }})(); |
Sample HTML that uses the fixed-header directive
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
<table class="table table-bordered" fixed-header> <thead> <tr> <th>Header 1</th> <th>Header 2</th> <th>Header 3</th> <th>Header 4</th> </tr> </thead> <tbody> <tr ng-repeat="item in [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]"> <td>Row {{item}} Col 1</td> <td>Row {{item}} Col 2</td> <td>Row {{item}} Col 3</td> <td>Row {{item}} Col 4</td> </tr> </tbody> <tfoot> <tr> <td>Footer 1</td> <td>Footer 2</td> <td>Footer 3</td> <td>Footer 4</td> </tr> </tfoot></table> |
The default height of the table body is 400px, to change this add a table-height attribute to the table element eg: table-height="500px".
UPDATE 08/10/2014: Added support for fixed footer (tfoot) element.
[转]AngularJS fixed header scrollable table directive的更多相关文章
- AngularJS:何时应该使用Directive、Controller、Service?
AngularJS:何时应该使用Directive.Controller.Service? (这篇文章你们一定要看,尤其初学的人,好吗亲?) 大漠穷秋 译 AngularJS是一款非常强大的前端MVC ...
- Part 10 AngularJS sort rows by table header
Here is what we want to do 1. The data should be sorted when the table column header is clicked 2. T ...
- AngularJS Best Practices: ng-include vs directive
For building an HTML template with reusable widgets like header, sidebar, footer, etc. Basically the ...
- AngularJS:何时应该使用Directive、Controller、Service?【新手必看】
(这篇文章你们一定要看,尤其初学的人,好吗亲?) 大漠穷秋 译 AngularJS是一款非常强大的前端MVC框架.同时,它也引入了相当多的概念,这些概念我们可能不是太熟悉.(译者注:老外真谦虚,我大天 ...
- AngularJs学习——何时应该使用Directive、Controller、Service?
翻译:大漠穷秋 原文链接:http://kirkbushell.me/when-to-use-directives-controllers-or-services-in-angular/ 一.简述 A ...
- [转]AngularJS:何时应该使用Directive、Controller、Service?
AngularJS是一款非常强大的前端MVC框架.同时,它也引入了相当多的概念,这些概念我们可能不是太熟悉.(译者注:老外真谦虚,我大天朝的码农对这些概念那是相当熟悉啊!)这些概念有: Directi ...
- [AngularJS] Build Your Own ng-controller Directive
/** * Created by Answer1215 on 12/21/2014. */ angular.module('app', []) .controller('FirstCtrl' , fu ...
- angularJS+requireJS实现controller及directive的按需加载
最近因为项目的比较大,需要加载的js文件较多,为了提高首屏页面的加载速度,需要对js文件进行按需加载,然后网上参考了一些资料,自己也深入研究一番之后,实现了按需加载控制器js文件及指令js文件的效果: ...
- AngularJS之Directive,scope,$parse
AngularJS内幕详解之 Directive AngularJS内幕详解之 Scope AngularJS的指令(Directive) compile和link的区别及使用示例 浅谈Angular ...
随机推荐
- 玩转Docker之常用命令篇(三)
首先我们来解决一个小问题,使用docker每次都要用sudo,为了让非root用户使用docker,可将当前用户添加到docker用户组: sudo groupadd docker sudo gpas ...
- WPF实现强大的动态公式计算
数据库可以定义表不同列之间的计算公式,进行自动公式计算,但如何实现行上的动态公式计算呢?行由于可以动态扩展,在某些应用场景下将能很好的解决实际问题. 1.VS2012新建一个WPF应用程序WpfApp ...
- Snabbt.js – 极简的 JavaScript 动画库
Snabbt.js 是一个简约的 JavaScript 动画库.它会平移,旋转,缩放,倾斜和调整你的元素.通过矩阵乘法运算,变换等可以任何你想要的方式进行组合.最终的结果通过 CSS3 变换矩阵设置. ...
- 你真的知道setTimeout是如何运行的吗
大家看下如下代码,猜猜执行结果: var start = new Date; setTimeout(function(){ console.log('时间流逝了:'+(new Date - start ...
- 安装 Ubuntu 后的个人常用配置
在 ASA 猪队友的带领下,拥抱开源世界,用上了Ubuntu.资深强迫症现身说法,配置符合自己使用习惯的Ubuntu. 1. 窗口标题栏显示菜单项 打开系统设置->外观->行为,在[显示窗 ...
- 导入CSV格式的数据
导入CSV格式的数据 (参见http://dev.mysql.com/doc/refman/5.6/en/load-data.html) 1.数据库表(st_pptn_r) CREATE TABLE ...
- 通过GP加载卫星云图-雷达图-降雨预报图
# ---------------------------------------------------------------------------# MeteorologicalImageLo ...
- Android中各种Drawable总结
在Android中,Drawable使用广泛,但是种类也多,基于<Android开发艺术探索>中对Drawable的讲解,总结了如下表格.
- iOS开发--Swift 基于MVC设计模式的简单的tableViewDemo
如果说MVC是最好的设计模式, 可能很多人并不赞同, 但是如果说MVC是最主流, 应用面最广的设计模式, 我想这是毫无争议的. 不说废话, 直接演示在Swift中如何使用MVC新建工程(我并没有新建文 ...
- 如何退出调起多个Activity的Application?
1.记录打开的Activity 每打开一个activity,即记录下来,需要关闭时,关闭每一个activity即可. 2.发送特定的广播 在需要结束应用时,发送一个特定广播,每个activity收到此 ...