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
diff --git a/web/gui/src/main/webapp/tests/app/fw/util/fn-spec.js b/web/gui/src/main/webapp/tests/app/fw/util/fn-spec.js
index 8838998..cbce523 100644
--- a/web/gui/src/main/webapp/tests/app/fw/util/fn-spec.js
+++ b/web/gui/src/main/webapp/tests/app/fw/util/fn-spec.js
@@ -213,7 +213,8 @@
         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 @@
         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();
+    });
+
 });
diff --git a/web/gui/src/main/webapp/tests/app/fw/widget/table-spec.js b/web/gui/src/main/webapp/tests/app/fw/widget/table-spec.js
index 107d27d..908ea16 100644
--- a/web/gui/src/main/webapp/tests/app/fw/widget/table-spec.js
+++ b/web/gui/src/main/webapp/tests/app/fw/widget/table-spec.js
@@ -32,7 +32,7 @@
                                 '<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 @@
 
         onosSortableHeaderTags = '<table ' +
                                 'onos-sortable-header ' +
-                                'sort-callback="sortCallback(urlSuffix)">' +
+                                'sort-callback="sortCallback(requestParams)">' +
                                 '<thead>' +
                                 '<tr>' +
                                 '<th colId="available"></th>' +
@@ -146,8 +146,12 @@
         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 {