Bri Prebilic Cole

GUI -- Tables with the "fixed-header" directive using ng-repeat will have fixed …

…headers while the body will scroll.

Change-Id: Ia1fed45e8da28375df3c34c068104802739e3c11
...@@ -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>
......