Bri Prebilic Cole

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
......@@ -150,6 +150,7 @@
return found;
}
// return true if the object is empty, return false otherwise
function isEmptyObject(obj) {
var key;
for (key in obj) {
......@@ -165,6 +166,16 @@
});
}
// return the parameter without a px suffix
function noPx(num) {
return Number(num.replace(/px$/, ''));
}
// return an element's given style property without px suffix
function noPxStyle(elem, prop) {
return Number(elem.style(prop).replace(/px$/, ''));
}
angular.module('onosUtil')
.factory('FnService', ['$window', function (_$window_) {
$window = _$window_;
......@@ -183,7 +194,9 @@
inArray: inArray,
removeFromArray: removeFromArray,
isEmptyObject: isEmptyObject,
cap: cap
cap: cap,
noPx: noPx,
noPxStyle: noPxStyle
};
}]);
......
......@@ -20,45 +20,74 @@
(function () {
'use strict';
var $log, $window, fs, is,
currCol = {},
prevCol = {},
tableIconTdSize = 33,
bottomMargin = 200;
// injected refs
var $log, $window, fs, is;
// Functions for creating a fixed header on a table (Angular Directive)
// constants
var tableIconTdSize = 33,
bottomMargin = 200,
colWidth = 'col-width',
tableIcon = 'table-icon';
function setTableWidth(t) {
var tHeaders, tdElement, colWidth, numIcons, numNonIcons,
winWidth = fs.windowSize().width;
// internal state
var currCol = {},
prevCol = {};
tHeaders = t.selectAll('th');
numIcons = 0;
numNonIcons = 0;
// Functions for creating a fixed header on a table (Angular Directive)
// FIXME: This should observe custom-set width from the HTML
function setElemWidth(elem, size) {
elem.style('width', size + 'px')
}
tHeaders.each(function(thElement, index) {
thElement = d3.select(this);
if (thElement.classed('table-icon')) {
numIcons = numIcons + 1;
function setColWidth(th, td, size) {
setElemWidth(th, size);
setElemWidth(td, size);
}
// count number of headers of
// - assigned width,
// - icon width,
// - and default width
// assumes assigned width is not given to icons
// returns the width of all columns that are not icons have an assigned width
function getDefaultWidth(headers) {
var winWidth = fs.windowSize().width,
iconCols = 0,
regCols = 0,
cstmColWidth = 0;
headers.each(function (d, i) {
var thElement = d3.select(this),
cstmWidth = thElement.attr(colWidth);
if (cstmWidth) {
cstmColWidth += fs.noPx(cstmWidth);
} else if (thElement.classed(tableIcon)) {
iconCols += 1;
} else {
numNonIcons = numNonIcons + 1;
regCols += 1;
}
});
colWidth = Math.floor((winWidth - (numIcons * tableIconTdSize)) / numNonIcons);
tHeaders.each(function(thElement, index) {
thElement = d3.select(this);
tdElement = t.select('td:nth-of-type(' + (index + 1) + ')');
return Math.floor((winWidth - cstmColWidth -
(iconCols * tableIconTdSize)) / regCols);
}
if (thElement.classed('table-icon')) {
thElement.style('width', tableIconTdSize + 'px');
tdElement.style('width', tableIconTdSize + 'px');
function setTableWidth(t) {
var tHeaders = t.selectAll('th'),
defaultColWidth = getDefaultWidth(tHeaders);
tHeaders.each(function (d, i) {
var thElement = d3.select(this),
tdElement = t.select('td:nth-of-type(' + (i + 1) + ')'),
custWidth = thElement.attr(colWidth);
if (custWidth) {
setColWidth(thElement, tdElement, fs.noPx(custWidth));
} else if (thElement.classed(tableIcon)) {
setColWidth(thElement, tdElement, tableIconTdSize);
} else {
thElement.style('width', colWidth + 'px');
tdElement.style('width', colWidth + 'px');
setColWidth(thElement, tdElement, defaultColWidth);
}
});
}
......
......@@ -75,11 +75,6 @@
return null;
}
function noPxWidth(elem) {
return Number(elem.style('width').replace(/px$/, ''));
}
// ==================================
function createToolbar(id, opts) {
......@@ -119,7 +114,7 @@
}
function adjustWidth(btnWidth) {
if (noPxWidth(currentRow) >= maxWidth) {
if (fs.noPxStyle(currentRow, 'width') >= maxWidth) {
tbWidth += btnWidth;
maxWidth = tbWidth;
}
......
......@@ -213,7 +213,8 @@ describe('factory: fw/util/fn.js', function() {
expect(fs.areFunctions(fs, [
'isF', 'isA', 'isS', 'isO', 'contains',
'areFunctions', 'areFunctionsNonStrict', 'windowSize', 'isMobile',
'find', 'inArray', 'removeFromArray', 'isEmptyObject', 'cap'
'find', 'inArray', 'removeFromArray', 'isEmptyObject', 'cap',
'noPx', 'noPxStyle'
])).toBeTruthy();
});
......@@ -387,4 +388,27 @@ describe('factory: fw/util/fn.js', function() {
expect(fs.cap('foo bar')).toEqual('Foo bar');
});
// === Tests for noPx()
it('should return the value without px suffix', function () {
expect(fs.noPx('10px')).toBe(10);
expect(fs.noPx('500px')).toBe(500);
expect(fs.noPx('-80px')).toBe(-80);
});
// === Tests for noPxStyle()
it("should give a style's property without px suffix", function () {
var d3Elem = d3.select('body')
.append('div')
.attr('id', 'fooElem')
.style({
width: '500px',
height: '200px',
'font-size': '12px'
});
expect(fs.noPxStyle(d3Elem, 'width')).toBe(500);
expect(fs.noPxStyle(d3Elem, 'height')).toBe(200);
expect(fs.noPxStyle(d3Elem, 'font-size')).toBe(12);
d3.select('#fooElem').remove();
});
});
......
......@@ -32,7 +32,7 @@ describe('factory: fw/widget/table.js', function () {
'<tr>' +
'<th></th>' +
'<th>Device ID </th>' +
'<th>H/W Version </th>' +
'<th col-width="100px">H/W Version </th>' +
'<th>S/W Version </th>' +
'</tr>' +
'</thead>' +
......@@ -51,7 +51,7 @@ describe('factory: fw/widget/table.js', function () {
onosSortableHeaderTags = '<table ' +
'onos-sortable-header ' +
'sort-callback="sortCallback(urlSuffix)">' +
'sort-callback="sortCallback(requestParams)">' +
'<thead>' +
'<tr>' +
'<th colId="available"></th>' +
......@@ -146,8 +146,12 @@ describe('factory: fw/widget/table.js', function () {
angular.forEach(thElems, function (thElem, i) {
thElem = angular.element(thElems[i]);
tdElem = angular.element(tbody.find('td').eq(i));
var custWidth = thElem.attr('col-width');
if (tdElem.attr('class') === 'table-icon') {
if (custWidth) {
expect(thElem.css('width')).toBe(custWidth);
expect(tdElem.css('width')).toBe(custWidth);
} else if (tdElem.attr('class') === 'table-icon') {
expect(thElem.css('width')).toBe(tableIconTdSize + 'px');
expect(tdElem.css('width')).toBe(tableIconTdSize + 'px');
} else {
......