GUI -- Tables with the "fixed-header" directive using ng-repeat will have fixed …
…headers while the body will scroll. Change-Id: Ia1fed45e8da28375df3c34c068104802739e3c11
Showing
5 changed files
with
84 additions
and
50 deletions
| ... | @@ -28,7 +28,6 @@ | ... | @@ -28,7 +28,6 @@ |
| 28 | <script type="text/javascript" src="../tp/angular-route.js"></script> | 28 | <script type="text/javascript" src="../tp/angular-route.js"></script> |
| 29 | 29 | ||
| 30 | <script type="text/javascript" src="../tp/d3.js"></script> | 30 | <script type="text/javascript" src="../tp/d3.js"></script> |
| 31 | - <script type="text/javascript" src="../tp/jquery-2.1.1.min.js"></script> | ||
| 32 | 31 | ||
| 33 | <script type="text/javascript" src="practice-table.js"></script> | 32 | <script type="text/javascript" src="practice-table.js"></script> |
| 34 | <script type="text/javascript" src="../app/fw/widget/widget.js"></script> | 33 | <script type="text/javascript" src="../app/fw/widget/widget.js"></script> | ... | ... |
| ... | @@ -235,45 +235,8 @@ | ... | @@ -235,45 +235,8 @@ |
| 235 | .controller('showTableCtrl', ['$log', '$scope', '$rootScope', | 235 | .controller('showTableCtrl', ['$log', '$scope', '$rootScope', |
| 236 | '$timeout', 'TableService', | 236 | '$timeout', 'TableService', |
| 237 | function ($log, $scope, $rootScope, $timeout, ts) { | 237 | function ($log, $scope, $rootScope, $timeout, ts) { |
| 238 | + var self = this; | ||
| 238 | var table = ts.renderTable(d3.select('#tableDiv'), config, deviceData); | 239 | var table = ts.renderTable(d3.select('#tableDiv'), config, deviceData); |
| 239 | - | ||
| 240 | - // --- commented out code below were various attempts at $apply --- | ||
| 241 | - // will delete unneeded dependencies once we have figured out which ones we need | ||
| 242 | - | ||
| 243 | - //$timeout(function () { | ||
| 244 | - // $log.log('inside timeout'); | ||
| 245 | - // //$scope.$watch('table', function (newVal, oldVal) { | ||
| 246 | - // $scope.$apply(); | ||
| 247 | - // //}); | ||
| 248 | - // }, 1000); | ||
| 249 | - | ||
| 250 | - //$scope.$applyAsync(); | ||
| 251 | - | ||
| 252 | - //$scope.$apply(function () { | ||
| 253 | - // ts.renderTable(d3.select('#tableDiv'), config, deviceData); | ||
| 254 | - //}); | ||
| 255 | - | ||
| 256 | - //$log.log($scope); | ||
| 257 | - | ||
| 258 | - //$scope.$watch('table', function(newVal, oldVal) { | ||
| 259 | - // //if (newVal === oldVal) { $log.log('hello'); return; } | ||
| 260 | - // $scope.$apply(); | ||
| 261 | - //}); | ||
| 262 | - // | ||
| 263 | - //$timeout(function () { | ||
| 264 | - // $log.log("in timeout in controller"); | ||
| 265 | - // $rootScope.$watch(function () { | ||
| 266 | - // return (table); | ||
| 267 | - // }, | ||
| 268 | - // function(newValue, oldValue) { | ||
| 269 | - // if(newValue) { | ||
| 270 | - // $log.log('hello??'); | ||
| 271 | - // //$rootScope.$apply(); | ||
| 272 | - // } | ||
| 273 | - // } | ||
| 274 | - // ); | ||
| 275 | - // //$scope.$apply(table); | ||
| 276 | - // $log.log("after scope.apply")}); | ||
| 277 | }]) | 240 | }]) |
| 278 | 241 | ||
| 279 | .directive('fixedHeader', ['$log', '$timeout', '$compile', | 242 | .directive('fixedHeader', ['$log', '$timeout', '$compile', |
| ... | @@ -285,8 +248,6 @@ | ... | @@ -285,8 +248,6 @@ |
| 285 | }, | 248 | }, |
| 286 | 249 | ||
| 287 | link: function (scope, element, attrs) { | 250 | link: function (scope, element, attrs) { |
| 288 | - $log.log("in directive"); | ||
| 289 | - | ||
| 290 | var table = d3.select(element[0]), | 251 | var table = d3.select(element[0]), |
| 291 | thead = table.select('thead'), | 252 | thead = table.select('thead'), |
| 292 | tbody = table.select('tbody'); | 253 | tbody = table.select('tbody'); | ... | ... |
| ... | @@ -26,12 +26,8 @@ table.summary-list { | ... | @@ -26,12 +26,8 @@ table.summary-list { |
| 26 | border-spacing: 0; | 26 | border-spacing: 0; |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | -/* TODO: delete overflow and block (handled by fixed-header directive) */ | ||
| 30 | table.summary-list tbody { | 29 | table.summary-list tbody { |
| 31 | - height: 500px; | ||
| 32 | border-radius: 0 0 8px 8px; | 30 | border-radius: 0 0 8px 8px; |
| 33 | - overflow: auto; | ||
| 34 | - display: block; | ||
| 35 | } | 31 | } |
| 36 | 32 | ||
| 37 | .light table.summary-list tr:nth-child(even) { | 33 | .light table.summary-list tr:nth-child(even) { |
| ... | @@ -66,7 +62,7 @@ table.summary-list th:last-child { | ... | @@ -66,7 +62,7 @@ table.summary-list th:last-child { |
| 66 | } | 62 | } |
| 67 | 63 | ||
| 68 | table.summary-list td { | 64 | table.summary-list td { |
| 69 | - padding: 5px; | 65 | + padding: 10px; |
| 70 | text-align: center; | 66 | text-align: center; |
| 71 | } | 67 | } |
| 72 | .dark table.summary-list td { | 68 | .dark table.summary-list td { | ... | ... |
| ... | @@ -22,8 +22,10 @@ | ... | @@ -22,8 +22,10 @@ |
| 22 | 22 | ||
| 23 | var $log; | 23 | var $log; |
| 24 | 24 | ||
| 25 | + // Render a plain d3 table by giving it the div, a config file, and data | ||
| 26 | + | ||
| 25 | function renderTable(div, config, data) { | 27 | function renderTable(div, config, data) { |
| 26 | - var table = div.append('table').attr('fixed-header', ''), | 28 | + var table = div.append('table'), |
| 27 | colIds = config.colIds, | 29 | colIds = config.colIds, |
| 28 | colText = config.colText, | 30 | colText = config.colText, |
| 29 | dataObjects = data[Object.keys(data)[0]], | 31 | dataObjects = data[Object.keys(data)[0]], |
| ... | @@ -58,6 +60,39 @@ | ... | @@ -58,6 +60,39 @@ |
| 58 | return table; | 60 | return table; |
| 59 | } | 61 | } |
| 60 | 62 | ||
| 63 | + // Functions for creating a fixed-header on a table (Angular Directive) | ||
| 64 | + | ||
| 65 | + function setColWidth(t) { | ||
| 66 | + var tHeaders, tdElement, colWidth; | ||
| 67 | + | ||
| 68 | + tHeaders = t.selectAll('th'); | ||
| 69 | + | ||
| 70 | + // select each td in the first row and set the header's width to the | ||
| 71 | + // corresponding td's width, if td is larger than header's width. | ||
| 72 | + tHeaders.each(function(thElement, index){ | ||
| 73 | + thElement = d3.select(this); | ||
| 74 | + | ||
| 75 | + tdElement = t.select('td:nth-of-type(' + (index + 1) + ')'); | ||
| 76 | + colWidth = tdElement.style('width'); | ||
| 77 | + | ||
| 78 | + thElement.style('width', colWidth); | ||
| 79 | + tdElement.style('width', colWidth); | ||
| 80 | + }); | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + function setCSS(thead, tbody, height) { | ||
| 84 | + thead.style('display', 'block'); | ||
| 85 | + tbody.style({'display': 'block', | ||
| 86 | + 'height': height || '500px', | ||
| 87 | + 'overflow': 'auto' | ||
| 88 | + }); | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + function fixTable(t, th, tb, height) { | ||
| 92 | + setColWidth(t); | ||
| 93 | + setCSS(th, tb, height); | ||
| 94 | + } | ||
| 95 | + | ||
| 61 | angular.module('onosWidget') | 96 | angular.module('onosWidget') |
| 62 | .factory('TableService', ['$log', function (_$log_) { | 97 | .factory('TableService', ['$log', function (_$log_) { |
| 63 | $log = _$log_; | 98 | $log = _$log_; |
| ... | @@ -65,6 +100,47 @@ | ... | @@ -65,6 +100,47 @@ |
| 65 | return { | 100 | return { |
| 66 | renderTable: renderTable | 101 | renderTable: renderTable |
| 67 | }; | 102 | }; |
| 68 | - }]); | 103 | + }]) |
| 104 | + | ||
| 105 | + .directive('fixedHeader', ['$timeout', function ($timeout) { | ||
| 106 | + return { | ||
| 107 | + restrict: 'A', | ||
| 108 | + scope: { | ||
| 109 | + tableHeight: '@' | ||
| 110 | + }, | ||
| 111 | + | ||
| 112 | + link: function (scope, element) { | ||
| 113 | + // TODO: look into other solutions than $timeout -- | ||
| 114 | + // fixed-header directive called before ng-repeat was | ||
| 115 | + // finished; using $scope.$emit to notify this directive | ||
| 116 | + // to fire was not working. | ||
| 117 | + $timeout(function() { | ||
| 118 | + var table = d3.select(element[0]), | ||
| 119 | + thead = table.select('thead'), | ||
| 120 | + tbody = table.select('tbody'); | ||
| 121 | + | ||
| 122 | + // wait until the table is visible | ||
| 123 | + // (offsetParent returns null if display is "none") | ||
| 124 | + scope.$watch( | ||
| 125 | + function () { | ||
| 126 | + return (!(table.offsetParent === null)); | ||
| 127 | + }, | ||
| 128 | + function(newValue) { | ||
| 129 | + if (newValue === true) { | ||
| 130 | + | ||
| 131 | + // ensure thead and tbody have no display | ||
| 132 | + thead.style('display', null); | ||
| 133 | + tbody.style('display', null); | ||
| 134 | + | ||
| 135 | + $timeout(function () { | ||
| 136 | + fixTable(table, thead, tbody, | ||
| 137 | + scope.tableHeight); | ||
| 138 | + }); | ||
| 139 | + } | ||
| 140 | + }); | ||
| 141 | + }, 200); | ||
| 142 | + } | ||
| 143 | + }; | ||
| 144 | + }]); | ||
| 69 | 145 | ||
| 70 | }()); | 146 | }()); | ... | ... |
| 1 | <!-- Device partial HTML --> | 1 | <!-- Device partial HTML --> |
| 2 | <div id="ov-device"> | 2 | <div id="ov-device"> |
| 3 | <h2>Device View</h2> | 3 | <h2>Device View</h2> |
| 4 | - <table class="summary-list"> | 4 | + <table class="summary-list" fixed-header> |
| 5 | - <tbody> | 5 | + <thead> |
| 6 | <tr> | 6 | <tr> |
| 7 | <th></th> | 7 | <th></th> |
| 8 | <th>URI</th> | 8 | <th>URI</th> |
| ... | @@ -12,7 +12,9 @@ | ... | @@ -12,7 +12,9 @@ |
| 12 | <th>Serial Number</th> | 12 | <th>Serial Number</th> |
| 13 | <th>Protocol</th> | 13 | <th>Protocol</th> |
| 14 | </tr> | 14 | </tr> |
| 15 | + </thead> | ||
| 15 | 16 | ||
| 17 | + <tbody> | ||
| 16 | <tr ng-repeat="dev in ctrl.deviceData"> | 18 | <tr ng-repeat="dev in ctrl.deviceData"> |
| 17 | <td><div icon icon-id="{{dev._iconid_available}}"></div></td> | 19 | <td><div icon icon-id="{{dev._iconid_available}}"></div></td> |
| 18 | <td>{{dev.id}}</td> | 20 | <td>{{dev.id}}</td> | ... | ... |
-
Please register or login to post a comment