GUI -- Allows for col-width="_px" to be specified in the html of table headers.
- Refactored table.js code - Added helper functions to FnService. - Deleted "sortable" from html in columns where sorting doesn't make sense (icons). - Updated unit tests to reflect changes Change-Id: I425101071bd5c7f237d64d98084a726cfce1d016
Showing
5 changed files
with
104 additions
and
39 deletions
... | @@ -150,6 +150,7 @@ | ... | @@ -150,6 +150,7 @@ |
150 | return found; | 150 | return found; |
151 | } | 151 | } |
152 | 152 | ||
153 | + // return true if the object is empty, return false otherwise | ||
153 | function isEmptyObject(obj) { | 154 | function isEmptyObject(obj) { |
154 | var key; | 155 | var key; |
155 | for (key in obj) { | 156 | for (key in obj) { |
... | @@ -165,6 +166,16 @@ | ... | @@ -165,6 +166,16 @@ |
165 | }); | 166 | }); |
166 | } | 167 | } |
167 | 168 | ||
169 | + // return the parameter without a px suffix | ||
170 | + function noPx(num) { | ||
171 | + return Number(num.replace(/px$/, '')); | ||
172 | + } | ||
173 | + | ||
174 | + // return an element's given style property without px suffix | ||
175 | + function noPxStyle(elem, prop) { | ||
176 | + return Number(elem.style(prop).replace(/px$/, '')); | ||
177 | + } | ||
178 | + | ||
168 | angular.module('onosUtil') | 179 | angular.module('onosUtil') |
169 | .factory('FnService', ['$window', function (_$window_) { | 180 | .factory('FnService', ['$window', function (_$window_) { |
170 | $window = _$window_; | 181 | $window = _$window_; |
... | @@ -183,7 +194,9 @@ | ... | @@ -183,7 +194,9 @@ |
183 | inArray: inArray, | 194 | inArray: inArray, |
184 | removeFromArray: removeFromArray, | 195 | removeFromArray: removeFromArray, |
185 | isEmptyObject: isEmptyObject, | 196 | isEmptyObject: isEmptyObject, |
186 | - cap: cap | 197 | + cap: cap, |
198 | + noPx: noPx, | ||
199 | + noPxStyle: noPxStyle | ||
187 | }; | 200 | }; |
188 | }]); | 201 | }]); |
189 | 202 | ... | ... |
... | @@ -20,45 +20,74 @@ | ... | @@ -20,45 +20,74 @@ |
20 | (function () { | 20 | (function () { |
21 | 'use strict'; | 21 | 'use strict'; |
22 | 22 | ||
23 | - var $log, $window, fs, is, | 23 | + // injected refs |
24 | - currCol = {}, | 24 | + var $log, $window, fs, is; |
25 | - prevCol = {}, | ||
26 | - tableIconTdSize = 33, | ||
27 | - bottomMargin = 200; | ||
28 | 25 | ||
29 | - // Functions for creating a fixed header on a table (Angular Directive) | 26 | + // constants |
27 | + var tableIconTdSize = 33, | ||
28 | + bottomMargin = 200, | ||
29 | + colWidth = 'col-width', | ||
30 | + tableIcon = 'table-icon'; | ||
30 | 31 | ||
31 | - function setTableWidth(t) { | 32 | + // internal state |
32 | - var tHeaders, tdElement, colWidth, numIcons, numNonIcons, | 33 | + var currCol = {}, |
33 | - winWidth = fs.windowSize().width; | 34 | + prevCol = {}; |
34 | 35 | ||
35 | - tHeaders = t.selectAll('th'); | 36 | + // Functions for creating a fixed header on a table (Angular Directive) |
36 | - numIcons = 0; | ||
37 | - numNonIcons = 0; | ||
38 | 37 | ||
39 | - // FIXME: This should observe custom-set width from the HTML | 38 | + function setElemWidth(elem, size) { |
39 | + elem.style('width', size + 'px') | ||
40 | + } | ||
40 | 41 | ||
41 | - tHeaders.each(function(thElement, index) { | 42 | + function setColWidth(th, td, size) { |
42 | - thElement = d3.select(this); | 43 | + setElemWidth(th, size); |
43 | - if (thElement.classed('table-icon')) { | 44 | + setElemWidth(td, size); |
44 | - numIcons = numIcons + 1; | 45 | + } |
46 | + | ||
47 | + // count number of headers of | ||
48 | + // - assigned width, | ||
49 | + // - icon width, | ||
50 | + // - and default width | ||
51 | + // assumes assigned width is not given to icons | ||
52 | + // returns the width of all columns that are not icons have an assigned width | ||
53 | + function getDefaultWidth(headers) { | ||
54 | + var winWidth = fs.windowSize().width, | ||
55 | + iconCols = 0, | ||
56 | + regCols = 0, | ||
57 | + cstmColWidth = 0; | ||
58 | + | ||
59 | + headers.each(function (d, i) { | ||
60 | + var thElement = d3.select(this), | ||
61 | + cstmWidth = thElement.attr(colWidth); | ||
62 | + | ||
63 | + if (cstmWidth) { | ||
64 | + cstmColWidth += fs.noPx(cstmWidth); | ||
65 | + } else if (thElement.classed(tableIcon)) { | ||
66 | + iconCols += 1; | ||
45 | } else { | 67 | } else { |
46 | - numNonIcons = numNonIcons + 1; | 68 | + regCols += 1; |
47 | } | 69 | } |
48 | }); | 70 | }); |
49 | 71 | ||
50 | - colWidth = Math.floor((winWidth - (numIcons * tableIconTdSize)) / numNonIcons); | 72 | + return Math.floor((winWidth - cstmColWidth - |
51 | - | 73 | + (iconCols * tableIconTdSize)) / regCols); |
52 | - tHeaders.each(function(thElement, index) { | 74 | + } |
53 | - thElement = d3.select(this); | ||
54 | - tdElement = t.select('td:nth-of-type(' + (index + 1) + ')'); | ||
55 | 75 | ||
56 | - if (thElement.classed('table-icon')) { | 76 | + function setTableWidth(t) { |
57 | - thElement.style('width', tableIconTdSize + 'px'); | 77 | + var tHeaders = t.selectAll('th'), |
58 | - tdElement.style('width', tableIconTdSize + 'px'); | 78 | + defaultColWidth = getDefaultWidth(tHeaders); |
79 | + | ||
80 | + tHeaders.each(function (d, i) { | ||
81 | + var thElement = d3.select(this), | ||
82 | + tdElement = t.select('td:nth-of-type(' + (i + 1) + ')'), | ||
83 | + custWidth = thElement.attr(colWidth); | ||
84 | + | ||
85 | + if (custWidth) { | ||
86 | + setColWidth(thElement, tdElement, fs.noPx(custWidth)); | ||
87 | + } else if (thElement.classed(tableIcon)) { | ||
88 | + setColWidth(thElement, tdElement, tableIconTdSize); | ||
59 | } else { | 89 | } else { |
60 | - thElement.style('width', colWidth + 'px'); | 90 | + setColWidth(thElement, tdElement, defaultColWidth); |
61 | - tdElement.style('width', colWidth + 'px'); | ||
62 | } | 91 | } |
63 | }); | 92 | }); |
64 | } | 93 | } | ... | ... |
... | @@ -75,11 +75,6 @@ | ... | @@ -75,11 +75,6 @@ |
75 | return null; | 75 | return null; |
76 | } | 76 | } |
77 | 77 | ||
78 | - function noPxWidth(elem) { | ||
79 | - return Number(elem.style('width').replace(/px$/, '')); | ||
80 | - } | ||
81 | - | ||
82 | - | ||
83 | // ================================== | 78 | // ================================== |
84 | 79 | ||
85 | function createToolbar(id, opts) { | 80 | function createToolbar(id, opts) { |
... | @@ -119,7 +114,7 @@ | ... | @@ -119,7 +114,7 @@ |
119 | } | 114 | } |
120 | 115 | ||
121 | function adjustWidth(btnWidth) { | 116 | function adjustWidth(btnWidth) { |
122 | - if (noPxWidth(currentRow) >= maxWidth) { | 117 | + if (fs.noPxStyle(currentRow, 'width') >= maxWidth) { |
123 | tbWidth += btnWidth; | 118 | tbWidth += btnWidth; |
124 | maxWidth = tbWidth; | 119 | maxWidth = tbWidth; |
125 | } | 120 | } | ... | ... |
... | @@ -213,7 +213,8 @@ describe('factory: fw/util/fn.js', function() { | ... | @@ -213,7 +213,8 @@ describe('factory: fw/util/fn.js', function() { |
213 | expect(fs.areFunctions(fs, [ | 213 | expect(fs.areFunctions(fs, [ |
214 | 'isF', 'isA', 'isS', 'isO', 'contains', | 214 | 'isF', 'isA', 'isS', 'isO', 'contains', |
215 | 'areFunctions', 'areFunctionsNonStrict', 'windowSize', 'isMobile', | 215 | 'areFunctions', 'areFunctionsNonStrict', 'windowSize', 'isMobile', |
216 | - 'find', 'inArray', 'removeFromArray', 'isEmptyObject', 'cap' | 216 | + 'find', 'inArray', 'removeFromArray', 'isEmptyObject', 'cap', |
217 | + 'noPx', 'noPxStyle' | ||
217 | ])).toBeTruthy(); | 218 | ])).toBeTruthy(); |
218 | }); | 219 | }); |
219 | 220 | ||
... | @@ -387,4 +388,27 @@ describe('factory: fw/util/fn.js', function() { | ... | @@ -387,4 +388,27 @@ describe('factory: fw/util/fn.js', function() { |
387 | expect(fs.cap('foo bar')).toEqual('Foo bar'); | 388 | expect(fs.cap('foo bar')).toEqual('Foo bar'); |
388 | }); | 389 | }); |
389 | 390 | ||
391 | + // === Tests for noPx() | ||
392 | + it('should return the value without px suffix', function () { | ||
393 | + expect(fs.noPx('10px')).toBe(10); | ||
394 | + expect(fs.noPx('500px')).toBe(500); | ||
395 | + expect(fs.noPx('-80px')).toBe(-80); | ||
396 | + }); | ||
397 | + | ||
398 | + // === Tests for noPxStyle() | ||
399 | + it("should give a style's property without px suffix", function () { | ||
400 | + var d3Elem = d3.select('body') | ||
401 | + .append('div') | ||
402 | + .attr('id', 'fooElem') | ||
403 | + .style({ | ||
404 | + width: '500px', | ||
405 | + height: '200px', | ||
406 | + 'font-size': '12px' | ||
407 | + }); | ||
408 | + expect(fs.noPxStyle(d3Elem, 'width')).toBe(500); | ||
409 | + expect(fs.noPxStyle(d3Elem, 'height')).toBe(200); | ||
410 | + expect(fs.noPxStyle(d3Elem, 'font-size')).toBe(12); | ||
411 | + d3.select('#fooElem').remove(); | ||
412 | + }); | ||
413 | + | ||
390 | }); | 414 | }); | ... | ... |
... | @@ -32,7 +32,7 @@ describe('factory: fw/widget/table.js', function () { | ... | @@ -32,7 +32,7 @@ describe('factory: fw/widget/table.js', function () { |
32 | '<tr>' + | 32 | '<tr>' + |
33 | '<th></th>' + | 33 | '<th></th>' + |
34 | '<th>Device ID </th>' + | 34 | '<th>Device ID </th>' + |
35 | - '<th>H/W Version </th>' + | 35 | + '<th col-width="100px">H/W Version </th>' + |
36 | '<th>S/W Version </th>' + | 36 | '<th>S/W Version </th>' + |
37 | '</tr>' + | 37 | '</tr>' + |
38 | '</thead>' + | 38 | '</thead>' + |
... | @@ -51,7 +51,7 @@ describe('factory: fw/widget/table.js', function () { | ... | @@ -51,7 +51,7 @@ describe('factory: fw/widget/table.js', function () { |
51 | 51 | ||
52 | onosSortableHeaderTags = '<table ' + | 52 | onosSortableHeaderTags = '<table ' + |
53 | 'onos-sortable-header ' + | 53 | 'onos-sortable-header ' + |
54 | - 'sort-callback="sortCallback(urlSuffix)">' + | 54 | + 'sort-callback="sortCallback(requestParams)">' + |
55 | '<thead>' + | 55 | '<thead>' + |
56 | '<tr>' + | 56 | '<tr>' + |
57 | '<th colId="available"></th>' + | 57 | '<th colId="available"></th>' + |
... | @@ -146,8 +146,12 @@ describe('factory: fw/widget/table.js', function () { | ... | @@ -146,8 +146,12 @@ describe('factory: fw/widget/table.js', function () { |
146 | angular.forEach(thElems, function (thElem, i) { | 146 | angular.forEach(thElems, function (thElem, i) { |
147 | thElem = angular.element(thElems[i]); | 147 | thElem = angular.element(thElems[i]); |
148 | tdElem = angular.element(tbody.find('td').eq(i)); | 148 | tdElem = angular.element(tbody.find('td').eq(i)); |
149 | + var custWidth = thElem.attr('col-width'); | ||
149 | 150 | ||
150 | - if (tdElem.attr('class') === 'table-icon') { | 151 | + if (custWidth) { |
152 | + expect(thElem.css('width')).toBe(custWidth); | ||
153 | + expect(tdElem.css('width')).toBe(custWidth); | ||
154 | + } else if (tdElem.attr('class') === 'table-icon') { | ||
151 | expect(thElem.css('width')).toBe(tableIconTdSize + 'px'); | 155 | expect(thElem.css('width')).toBe(tableIconTdSize + 'px'); |
152 | expect(tdElem.css('width')).toBe(tableIconTdSize + 'px'); | 156 | expect(tdElem.css('width')).toBe(tableIconTdSize + 'px'); |
153 | } else { | 157 | } else { | ... | ... |
-
Please register or login to post a comment