GUI -- Table headers can dynamically display with an icon which sorting direction the table is currently sorted as.

Change-Id: I6c5e6d1c196495dc6065ae58fa6cb21001c01778
diff --git a/web/gui/src/main/webapp/app/fw/svg/icon.js b/web/gui/src/main/webapp/app/fw/svg/icon.js
index bd686f7..e3f4bdb 100644
--- a/web/gui/src/main/webapp/app/fw/svg/icon.js
+++ b/web/gui/src/main/webapp/app/fw/svg/icon.js
@@ -161,6 +161,28 @@
         return g;
     }
 
+    function createSortIcon() {
+       function sortAsc(div) {
+            div.style('display', 'inline-block');
+            loadEmbeddedIcon(div, 'tableColSortAsc', 10);
+        }
+
+        function sortDesc(div) {
+            div.style('display', 'inline-block');
+            loadEmbeddedIcon(div, 'tableColSortDesc', 10);
+        }
+
+        function sortNone(div) {
+            div.remove();
+        }
+
+        return {
+            sortAsc: sortAsc,
+            sortDesc: sortDesc,
+            sortNone: sortNone
+        };
+    }
+
 
     // =========================
     // === DEFINE THE MODULE
@@ -180,7 +202,8 @@
                 loadEmbeddedIcon: loadEmbeddedIcon,
                 addDeviceIcon: addDeviceIcon,
                 addHostIcon: addHostIcon,
-                iconConfig: function () { return config; }
+                iconConfig: function () { return config; },
+                createSortIcon: createSortIcon
             };
         }]);
 
diff --git a/web/gui/src/main/webapp/app/fw/widget/table.js b/web/gui/src/main/webapp/app/fw/widget/table.js
index 5cf283e..d28fa0d 100644
--- a/web/gui/src/main/webapp/app/fw/widget/table.js
+++ b/web/gui/src/main/webapp/app/fw/widget/table.js
@@ -20,7 +20,7 @@
 (function () {
     'use strict';
 
-    var $window, fs,
+    var $log, $window, fs, is,
         bottomMargin = 200;
 
     // Render a plain d3 table by giving it the div, a config file, and data
@@ -101,9 +101,9 @@
         });
     }
 
-    function fixTable(t, th, tb, height) {
+    function fixTable(t, th, tb) {
         setTableWidth(t);
-        setTableHeight(th, tb, height);
+        setTableHeight(th, tb);
     }
 
     angular.module('onosWidget')
@@ -137,6 +137,7 @@
 
                     scope.setTableHW = function () {
                         scope.$on('LastElement', function (event) {
+                            // only adjust the table once it's completely loaded
                             fixTable(table, thead, tbody);
                             shouldResize = true;
                         });
@@ -153,6 +154,70 @@
                 });
             };
 
+        }])
+
+        .directive('onosSortableHeader', ['$log', 'IconService',
+            function (_$log_, _is_) {
+            return function (scope, element, attrs) {
+                $log = _$log_;
+                is = _is_;
+                var table = d3.select(element[0]),
+                    currCol = {},
+                    prevCol = {},
+                    sortIconAPI = is.createSortIcon();
+
+                // when a header is clicked, change its icon tag and get sorting
+                // order to send to the server.
+                table.selectAll('th').on('click', function () {
+                    var thElem = d3.select(this),
+                        div;
+
+                    currCol.colId = thElem.attr('colId');
+
+                    if (currCol.colId === prevCol.colId) {
+                        (currCol.icon === 'tableColSortDesc') ?
+                            currCol.icon = 'tableColSortAsc' :
+                            currCol.icon = 'tableColSortDesc';
+                        prevCol.icon = currCol.icon;
+                    } else {
+                        currCol.icon = 'tableColSortAsc';
+                        prevCol.icon = 'tableColSortNone';
+                    }
+
+                    $log.debug('currCol clicked: ' + currCol.colId +
+                    ', with sorting icon: ' + currCol.icon);
+                    $log.debug('prevCol clicked: ' + prevCol.colId +
+                    ', with its current sorting icon as ' + prevCol.icon);
+
+                    div = thElem.select('div');
+                    div.remove();
+
+                    div = thElem.append('div');
+
+                    if (currCol.icon === 'tableColSortAsc') {
+                        sortIconAPI.sortAsc(div);
+                    } else {
+                        sortIconAPI.sortDesc(div);
+                    }
+
+                    if (prevCol.colId !== undefined &&
+                        prevCol.icon === 'tableColSortNone') {
+                        sortIconAPI.sortNone(prevCol.elem.select('div'));
+                    }
+
+                    prevCol.colId = currCol.colId;
+                    prevCol.elem = thElem;
+
+                });
+
+                // TODO: send the prev and currCol info to the server to use in sorting table
+
+                // TODO: figure out timing of events:
+                // updating the icon
+                // sending the column sorting info to the server
+                // refreshing the table so that the new rows will be sorted
+
+            }
         }]);
 
 }());
diff --git a/web/gui/src/main/webapp/app/view/device/device.html b/web/gui/src/main/webapp/app/view/device/device.html
index aef1228..f8a62a0 100644
--- a/web/gui/src/main/webapp/app/view/device/device.html
+++ b/web/gui/src/main/webapp/app/view/device/device.html
@@ -4,6 +4,7 @@
     <table class="summary-list"
            onos-fixed-header
            ng-style="setTableHW()"
+           onos-sortable-header
            sort-callback="ctrl.sortCallback()">
         <thead>
             <tr>
diff --git a/web/gui/src/main/webapp/app/view/device/device.js b/web/gui/src/main/webapp/app/view/device/device.js
index b607936..0d7779c 100644
--- a/web/gui/src/main/webapp/app/view/device/device.js
+++ b/web/gui/src/main/webapp/app/view/device/device.js
@@ -20,9 +20,6 @@
 
 (function () {
     'use strict';
-    var currCol = {},
-        prevCol = {};
-
 
     angular.module('ovDevice', [])
         .controller('OvDeviceCtrl', ['$log', '$location', 'RestService',
@@ -38,31 +35,6 @@
                 self.deviceData = data.devices;
             });
 
-            d3.selectAll('th').on('click', function () {
-                var thElem = d3.select(this);
-                currCol.colId = thElem.attr('colId');
-
-                if(currCol.colId === prevCol.colId) {
-                    (currCol.icon === 'tableColSortDesc') ?
-                        currCol.icon = 'tableColSortAsc' :
-                        currCol.icon = 'tableColSortDesc';
-                    prevCol.icon = currCol.icon;
-                } else {
-                    currCol.icon = 'tableColSortAsc';
-                    prevCol.icon = 'tableColSortNone';
-                }
-
-                $log.debug('currCol clicked: ' + currCol.colId +
-                ', with sorting icon: ' + currCol.icon);
-                $log.debug('prevCol clicked: ' + prevCol.colId +
-                ', with its current sorting icon as ' + prevCol.icon);
-
-                // TODO: send the prev and currCol info to the server to use in sorting table here
-
-                prevCol.colId = currCol.colId;
-
-            });
-
             $log.log('OvDeviceCtrl has been created');
         }]);
 }());