From 852f6993978638697cfed6d2fb4f2a0d7cbb3de2 Mon Sep 17 00:00:00 2001 From: Lourens Schep Date: Thu, 15 Sep 2016 14:57:52 -0300 Subject: [PATCH] feat(emptyBaseLayer): made emptyBaseLayer module to create grid background Made a new feature called 'emptyBaseLayer'. This can be added to the ui-grid by using ui-grid-empty-base-layer. This creates a fake background for the ui-grid of continues rows, the rows are not editable or clickable, and just act as a background. There also is a new tutorial page '218 Empty Base Layer' --- misc/site/data/5.json | 27 +++ misc/tutorial/218_empty_grid_base_layer.ngdoc | 50 ++++++ .../empty-base-layer/js/emptyBaseLayer.js | 164 ++++++++++++++++++ .../empty-base-layer/less/emptyBaseLayer.less | 8 + .../templates/emptyBaseLayerContainer.html | 13 ++ .../test/emptyBaseLayer.spec.js | 94 ++++++++++ 6 files changed, 356 insertions(+) create mode 100644 misc/site/data/5.json create mode 100644 misc/tutorial/218_empty_grid_base_layer.ngdoc create mode 100644 src/features/empty-base-layer/js/emptyBaseLayer.js create mode 100644 src/features/empty-base-layer/less/emptyBaseLayer.less create mode 100644 src/features/empty-base-layer/templates/emptyBaseLayerContainer.html create mode 100644 src/features/empty-base-layer/test/emptyBaseLayer.spec.js diff --git a/misc/site/data/5.json b/misc/site/data/5.json new file mode 100644 index 0000000000..6d9c868d69 --- /dev/null +++ b/misc/site/data/5.json @@ -0,0 +1,27 @@ +[ + { + "name": "Frederick Howard", + "gender": "male", + "company": "Zilch" + }, + { + "name": "Joseph Meyers", + "gender": "female", + "company": "Roughies" + }, + { + "name": "Leta Rogers", + "gender": "female", + "company": "Phormula" + }, + { + "name": "Tyler Campbell", + "gender": "male", + "company": "Soprano" + }, + { + "name": "Diane Stuart", + "gender": "female", + "company": "Proxsoft" + } +] diff --git a/misc/tutorial/218_empty_grid_base_layer.ngdoc b/misc/tutorial/218_empty_grid_base_layer.ngdoc new file mode 100644 index 0000000000..552f8dc694 --- /dev/null +++ b/misc/tutorial/218_empty_grid_base_layer.ngdoc @@ -0,0 +1,50 @@ +@ngdoc overview +@name Tutorial: 218 Empty Grid Base Layer +@description + + + +@example + + + var app = angular.module('app', ['ngTouch', 'ui.grid', 'ui.grid.resizeColumns', + 'ui.grid.moveColumns', 'ui.grid.emptyBaseLayer', 'ui.grid.autoResize', 'ui.grid.pinning']); + + app.controller('MainCtrl', ['$scope', '$http', function ($scope, $http) { + $scope.gridOptions = { + enableSorting: true, + columnDefs: [ + { field: 'name', minWidth: 100, width: 150, enableColumnResizing: false, pinnedLeft:true}, + { field: 'gender', width: '40%', maxWidth: 200, minWidth: 70 }, + { field: 'company', width: '30%' } + ] + }; + + $scope.randomSize = function () { + var newHeight = Math.floor(Math.random() * (300 - 100 + 1) + 300), + newWidth = Math.floor(Math.random() * (600 - 200 + 1) + 200); + + angular.element(document.getElementsByClassName('grid')[0]).css('height', newHeight + 'px'); + angular.element(document.getElementsByClassName('grid')[0]).css('width', newWidth + 'px'); + }; + + $http.get('/data/5.json') + .success(function(data) { + $scope.gridOptions.data = data; + }); + }]); + + +
+ +
+
+
+
+ + .grid { + width: 500px; + height: 400px; + } + +
diff --git a/src/features/empty-base-layer/js/emptyBaseLayer.js b/src/features/empty-base-layer/js/emptyBaseLayer.js new file mode 100644 index 0000000000..edb6b6e03e --- /dev/null +++ b/src/features/empty-base-layer/js/emptyBaseLayer.js @@ -0,0 +1,164 @@ +(function () { + 'use strict'; + + /** + * @ngdoc overview + * @name ui.grid.emptyBaseLayer + * @description + * + * # ui.grid.emptyBaseLayer + * + * + * + * This module provides the ability to have the background of the ui-grid be empty rows, this would be displayed in the case were + * the grid height is greater then the amount of rows displayed. + * + *
+ */ + var module = angular.module('ui.grid.emptyBaseLayer', ['ui.grid']); + + + /** + * @ngdoc service + * @name ui.grid.emptyBaseLayer.service:uiGridBaseLayerService + * + * @description Services for the empty base layer grid + */ + module.service('uiGridBaseLayerService', ['gridUtil', '$compile', function (gridUtil, $compile) { + var service = { + initializeGrid: function (grid, disableEmptyBaseLayer) { + + /** + * @ngdoc object + * @name ui.grid.emptyBaseLayer.api:GridOptions + * + * @description GridOptions for emptyBaseLayer feature, these are available to be + * set using the ui-grid {@link ui.grid.class:GridOptions gridOptions} + */ + grid.baseLayer = { + emptyRows: [] + }; + + /** + * @ngdoc object + * @name enableEmptyGridBaseLayer + * @propertyOf ui.grid.emptyBaseLayer.api:GridOptions + * @description Enable empty base layer, which shows empty rows as background on the entire grid + *
Defaults to true, if the directive is used. + *
Set to false either by setting this attribute or passing false to the directive. + */ + //default option to true unless it was explicitly set to false + if (grid.options.enableEmptyGridBaseLayer !== false) { + grid.options.enableEmptyGridBaseLayer = !disableEmptyBaseLayer; + } + }, + + setNumberOfEmptyRows: function(viewportHeight, grid) { + var rowHeight = grid.options.rowHeight, + rows = Math.ceil(viewportHeight / rowHeight); + if (rows > 0) { + grid.baseLayer.emptyRows = []; + for (var i = 0; i < rows; i++) { + grid.baseLayer.emptyRows.push({}); + } + } + } + }; + return service; + }]); + + /** + * @ngdoc object + * @name ui.grid.emptyBaseLayer.directive:uiGridEmptyBaseLayer + * @description Shows empty rows in the background of the ui-grid, these span + * the full height of the ui-grid, so that there won't be blank space below the shown rows. + * @example + *
+   *  
+ *
+ * Or you can enable/disable it dynamically by passing in true or false. It doesn't + * the value, so it would only be set on initial render. + *
+   *  
+ *
+ */ + module.directive('uiGridEmptyBaseLayer', ['gridUtil', 'uiGridBaseLayerService', + '$parse', + function (gridUtil, uiGridBaseLayerService, $parse) { + return { + require: '^uiGrid', + scope: false, + compile: function ($elm, $attrs) { + return { + pre: function ($scope, $elm, $attrs, uiGridCtrl) { + var disableEmptyBaseLayer = $parse($attrs.uiGridEmptyBaseLayer)($scope) === false; + uiGridBaseLayerService.initializeGrid(uiGridCtrl.grid, disableEmptyBaseLayer); + }, + post: function ($scope, $elm, $attrs, uiGridCtrl) { + if (!uiGridCtrl.grid.options.enableEmptyGridBaseLayer) { + return; + } + + var renderBodyContainer = uiGridCtrl.grid.renderContainers.body, + viewportHeight = renderBodyContainer.getViewportHeight(); + + function heightHasChanged() { + var newViewPortHeight = renderBodyContainer.getViewportHeight(); + + if (newViewPortHeight !== viewportHeight) { + viewportHeight = newViewPortHeight; + return true; + } + return false; + } + + function getEmptyBaseLayerCss(viewportHeight) { + var ret = ''; + // Set ui-grid-empty-base-layer height + ret += '\n .grid' + uiGridCtrl.grid.id + + ' .ui-grid-render-container ' + + '.ui-grid-empty-base-layer-container.ui-grid-canvas ' + + '{ height: ' + viewportHeight + 'px; }'; + return ret; + } + + uiGridCtrl.grid.registerStyleComputation({ + func: function() { + if (heightHasChanged()) { + uiGridBaseLayerService.setNumberOfEmptyRows(viewportHeight, uiGridCtrl.grid); + } + return getEmptyBaseLayerCss(viewportHeight); + } + }); + } + }; + } + }; + }]); + + /** + * @ngdoc directive + * @name ui.grid.emptyBaseLayer.directive:uiGridViewport + * @description stacks on the uiGridViewport directive to append the empty grid base layer html elements to the + * default gridRow template + */ + module.directive('uiGridViewport', + ['$compile', 'gridUtil', '$templateCache', + function ($compile, gridUtil, $templateCache) { + return { + priority: -200, + scope: false, + compile: function ($elm, $attrs) { + var emptyBaseLayerContainer = $templateCache.get('ui-grid/emptyBaseLayerContainer'); + $elm.prepend(emptyBaseLayerContainer); + return { + pre: function ($scope, $elm, $attrs, controllers) { + }, + post: function ($scope, $elm, $attrs, controllers) { + } + }; + } + }; + }]); + +})(); diff --git a/src/features/empty-base-layer/less/emptyBaseLayer.less b/src/features/empty-base-layer/less/emptyBaseLayer.less new file mode 100644 index 0000000000..5ec5cc1474 --- /dev/null +++ b/src/features/empty-base-layer/less/emptyBaseLayer.less @@ -0,0 +1,8 @@ +@import '../../../less/variables'; + +.ui-grid-viewport .ui-grid-empty-base-layer-container { + position: absolute; + overflow: hidden; + pointer-events: none; + z-index: -1; +} diff --git a/src/features/empty-base-layer/templates/emptyBaseLayerContainer.html b/src/features/empty-base-layer/templates/emptyBaseLayerContainer.html new file mode 100644 index 0000000000..a5e42546be --- /dev/null +++ b/src/features/empty-base-layer/templates/emptyBaseLayerContainer.html @@ -0,0 +1,13 @@ +
+
+
+
+
+
+
+
+
+
diff --git a/src/features/empty-base-layer/test/emptyBaseLayer.spec.js b/src/features/empty-base-layer/test/emptyBaseLayer.spec.js new file mode 100644 index 0000000000..57fd8089a8 --- /dev/null +++ b/src/features/empty-base-layer/test/emptyBaseLayer.spec.js @@ -0,0 +1,94 @@ +describe('ui.grid.emptyBaseLayer', function () { + + var scope, element, viewportHeight, emptyBaseLayerContainer, $compile; + + beforeEach(module('ui.grid.emptyBaseLayer')); + + beforeEach(inject(function (_$compile_, $rootScope, $httpBackend) { + + $compile = _$compile_; + scope = $rootScope; + + viewportHeight = "100"; + scope.gridOptions = {}; + scope.gridOptions.data = [ + { col1: 'col1', col2: 'col2' } + ]; + scope.gridOptions.onRegisterApi = function (gridApi) { + scope.gridApi = gridApi; + scope.grid = gridApi.grid; + var renderBodyContainer = scope.grid.renderContainers.body; + spyOn(renderBodyContainer, 'getViewportHeight').and.callFake(function() { + return viewportHeight; + }); + }; + })); + + describe('enabled', function() { + beforeEach(function() { + element = angular.element('
'); + + $compile(element)(scope); + scope.$digest(); + + emptyBaseLayerContainer = angular.element(element.find('.ui-grid-empty-base-layer-container')[0]); + }); + + it('should add emptyBaseLayerContainer to the viewport html', function () { + expect(element.find('.ui-grid-empty-base-layer-container').length).toBe(1); + }); + + it('should add fake rows to the empty base layer container, on building styles', function() { + expect(emptyBaseLayerContainer.children().length).toBe(4); + }); + + it('should increase in rows if viewport height increased', function() { + viewportHeight = "150"; + scope.grid.buildStyles(); + scope.$digest(); + expect(emptyBaseLayerContainer.children().length).toBe(5); + }); + }); + + describe('disabled', function() { + it('should be disabled if we pass false into the directive in the markup', function() { + element = angular.element('
'); + $compile(element)(scope); + scope.$digest(); + emptyBaseLayerContainer = angular.element(element.find('.ui-grid-empty-base-layer-container')[0]); + expect(emptyBaseLayerContainer.children().length).toBe(0); + }); + + it('should be disabled if we pass false as an value through the scope in markup', function() { + scope.enableEmptyBaseLayer = false; + element = angular.element('
'); + $compile(element)(scope); + scope.$digest(); + emptyBaseLayerContainer = angular.element(element.find('.ui-grid-empty-base-layer-container')[0]); + expect(emptyBaseLayerContainer.children().length).toBe(0); + }); + + it('should be disabled if set enableEmptyGridBaseLayer in gridOptions to false', function() { + scope.gridOptions.enableEmptyGridBaseLayer = false; + element = angular.element('
'); + $compile(element)(scope); + scope.$digest(); + emptyBaseLayerContainer = angular.element(element.find('.ui-grid-empty-base-layer-container')[0]); + expect(emptyBaseLayerContainer.children().length).toBe(0); + }); + + it('should not reset the number of rows incase it is disabled', function() { + scope.gridOptions.enableEmptyGridBaseLayer = false; + element = angular.element('
'); + $compile(element)(scope); + scope.$digest(); + emptyBaseLayerContainer = angular.element(element.find('.ui-grid-empty-base-layer-container')[0]); + expect(emptyBaseLayerContainer.children().length).toBe(0); + + viewportHeight = "150"; + scope.grid.buildStyles(); + scope.$digest(); + expect(emptyBaseLayerContainer.children().length).toBe(0); + }); + }); +});