| /* |
| * Copyright 2015 Open Networking Laboratory |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* |
| ONOS GUI -- Widget -- Table Service |
| */ |
| (function () { |
| 'use strict'; |
| |
| // injected refs |
| var $log, $window, fs, mast, is; |
| |
| // constants |
| var tableIconTdSize = 33, |
| pdg = 22, |
| colWidth = 'col-width', |
| tableIcon = 'table-icon', |
| asc = 'asc', |
| desc = 'desc', |
| none = 'none'; |
| |
| // internal state |
| var currCol = {}, |
| prevCol = {}, |
| sortIconAPI; |
| |
| // Functions for creating a scrolling table body with fixed table header |
| |
| function _width(elem, width) { |
| elem.style('width', width); |
| } |
| |
| function defaultSize(table, width) { |
| var thead = table.select('.table-header').select('table'), |
| tbody = table.select('.table-body').select('table'), |
| wpx = width + 'px'; |
| _width(thead, wpx); |
| _width(tbody, wpx); |
| } |
| |
| function adjustTable(table, width, height) { |
| var thead = table.select('.table-header').select('table'), |
| tbodyDiv = table.select('.table-body'), |
| tbody = tbodyDiv.select('table'), |
| cstmWidths = {}; |
| |
| function findCstmWidths() { |
| var headers = thead.selectAll('td'); |
| |
| headers.each(function (d, i) { |
| var h = d3.select(this), |
| index = i.toString(); |
| if (h.classed(tableIcon)) { |
| cstmWidths[index] = tableIconTdSize + 'px'; |
| } |
| if (h.attr(colWidth)) { |
| cstmWidths[index] = h.attr(colWidth); |
| } |
| }); |
| $log.debug('Headers with custom widths: ', cstmWidths); |
| } |
| |
| function setTdWidths(elem) { |
| var tds = elem.selectAll('tr:not(.ignore-width)').selectAll('td'); |
| _width(elem, width + 'px'); |
| |
| tds.each(function (d, i) { |
| var td = d3.select(this), |
| index = i.toString(); |
| if (cstmWidths.hasOwnProperty(index)) { |
| _width(td, cstmWidths[index]); |
| } |
| }); |
| } |
| |
| function setHeight(body) { |
| var h = height - (mast.mastHeight() + |
| fs.noPxStyle(d3.select('.tabular-header'), 'height') + |
| fs.noPxStyle(thead, 'height') + pdg); |
| body.style('height', h + 'px'); |
| } |
| |
| findCstmWidths(); |
| setTdWidths(thead); |
| setTdWidths(tbody); |
| setHeight(tbodyDiv); |
| |
| cstmWidths = {}; |
| } |
| |
| // Functions for sorting table rows by header |
| |
| function updateSortDirection(thElem) { |
| sortIconAPI.sortNone(thElem.select('div')); |
| currCol.div = thElem.append('div'); |
| currCol.colId = thElem.attr('colId'); |
| |
| if (currCol.colId === prevCol.colId) { |
| (currCol.dir === desc) ? currCol.dir = asc : currCol.dir = desc; |
| prevCol.dir = currCol.dir; |
| } else { |
| currCol.dir = asc; |
| prevCol.dir = none; |
| } |
| (currCol.dir === asc) ? |
| sortIconAPI.sortAsc(currCol.div) : sortIconAPI.sortDesc(currCol.div); |
| |
| if (prevCol.colId && prevCol.dir === none) { |
| sortIconAPI.sortNone(prevCol.div); |
| } |
| |
| prevCol.colId = currCol.colId; |
| prevCol.div = currCol.div; |
| } |
| |
| function sortRequestParams() { |
| return { |
| sortCol: currCol.colId, |
| sortDir: currCol.dir |
| }; |
| } |
| |
| function resetSort() { |
| if (currCol.div) { |
| sortIconAPI.sortNone(currCol.div); |
| } |
| if (prevCol.div) { |
| sortIconAPI.sortNone(prevCol.div); |
| } |
| currCol = {}; |
| prevCol = {}; |
| } |
| |
| angular.module('onosWidget') |
| .directive('onosFixedHeader', ['$log','$window', |
| 'FnService', 'MastService', |
| |
| function (_$log_, _$window_, _fs_, _mast_) { |
| return function (scope, element) { |
| $log = _$log_; |
| $window = _$window_; |
| fs = _fs_; |
| mast = _mast_; |
| |
| var table = d3.select(element[0]), |
| canAdjust = false; |
| |
| scope.$watchCollection(function () { |
| return { |
| h: $window.innerHeight, |
| w: $window.innerWidth |
| }; |
| }, function () { |
| var wsz = fs.windowSize(0, 30), |
| wWidth = wsz.width, |
| wHeight = wsz.height; |
| |
| if (!scope.tableData.length) { |
| defaultSize(table, wWidth); |
| } |
| |
| scope.$on('LastElement', function () { |
| // only adjust the table once it's completely loaded |
| adjustTable(table, wWidth, wHeight); |
| canAdjust = true; |
| }); |
| |
| if (canAdjust) { |
| adjustTable(table, wWidth, wHeight); |
| } |
| }); |
| }; |
| }]) |
| |
| .directive('onosSortableHeader', ['$log', 'IconService', |
| function (_$log_, _is_) { |
| return { |
| scope: { |
| ctrlCallback: '&sortCallback' |
| }, |
| link: function (scope, element) { |
| $log = _$log_; |
| is = _is_; |
| var header = d3.select(element[0]); |
| sortIconAPI = is.sortIcons(); |
| |
| // when a header is clicked, change its sort direction |
| // and get sorting order to send to the server. |
| header.selectAll('td').on('click', function () { |
| var col = d3.select(this); |
| |
| if (col.attr('sortable') === '') { |
| updateSortDirection(col); |
| scope.ctrlCallback({ |
| requestParams: sortRequestParams() |
| }); |
| } |
| }); |
| } |
| }; |
| }]) |
| |
| .factory('TableService', ['IconService', |
| |
| function (is) { |
| sortIconAPI = is.sortIcons(); |
| |
| return { |
| resetSort: resetSort |
| }; |
| }]); |
| |
| }()); |