• [转]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:

    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.

  • 相关阅读:
    了解node.js
    RC4 in TLS is Broken: Now What?
    LDAP 在ubuntu14.04下的安装配置install and configure
    Bucking the stigma (留学生请摘掉有色眼镜看社区大学)
    SSL Labs: Increased Penalty When TLS 1.2 Is Not Supported
    PostgresQL中的NUlls first/last功能
    网页小工具集合
    T-SQL在线格式化工具
    sudoers文件解析
    Java提高篇——JVM加载class文件的原理机制
  • 原文地址:https://www.cnblogs.com/freeliver54/p/5234817.html
Copyright © 2020-2023  润新知