Skip to content

Commit 420a0dc

Browse files
committed
fix(uiGrid): Fix elm height calc for hidden grids
The header row height could not be calculated when the grid was hidden, because the absolutely-positioned cells did not count towards the container height. To fix this, I made changes to the elementHeight/elementWidth functions that will, if the element in question is hidden, append the element to the document body with visibility: hidden. I also had to switch the cells from being absolutely positioned to relatively positioned and floated left. Hopefully this will not have any further repercussions
1 parent 0b8113c commit 420a0dc

File tree

6 files changed

+95
-13
lines changed

6 files changed

+95
-13
lines changed

src/js/core/directives/ui-grid-style.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@
6868
var ret = '';
6969
var left = 0;
7070
uiGridCtrl.grid.options.columnDefs.forEach(function(c, i) {
71-
ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + i + ' { width: ' + equalWidth + 'px; left: ' + left + 'px; }';
71+
// ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + i + ' { width: ' + equalWidth + 'px; left: ' + left + 'px; }';
72+
ret = ret + ' .grid' + uiGridCtrl.grid.id + ' .col' + i + ' { width: ' + equalWidth + 'px; }';
7273
left = left + equalWidth;
7374
});
7475

src/js/core/directives/ui-grid.js

+8-5
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
* @description Creates a new grid instance. Each instance will have a unique id
2828
* @returns {Grid} grid
2929
*/
30-
createGrid : function(){
30+
createGrid : function() {
3131
var grid = new Grid(gridUtil.newId());
3232
grid.registerColumnBuilder(service.defaultColumnBuilder);
3333
return grid;
@@ -280,7 +280,9 @@
280280
// NOTE: viewport drawable height is the height of the grid minus the header row height (including any border)
281281
// TODO(c0bra): account for footer height
282282
Grid.prototype.getViewportHeight = function () {
283-
return this.gridHeight - this.headerHeight;
283+
var viewPortHeight = this.gridHeight - this.headerHeight;
284+
$log.debug('viewPortHeight', viewPortHeight);
285+
return viewPortHeight;
284286
};
285287

286288
Grid.prototype.getCanvasHeight = function () {
@@ -478,6 +480,7 @@
478480
$scope.grid.refreshCanvas = self.refreshCanvas = function() {
479481
if (self.header) {
480482
self.grid.headerHeight = gridUtil.outerElementHeight(self.header);
483+
$log.debug('self.grid.headerHeight', self.grid.headerHeight);
481484
}
482485

483486
self.grid.buildStyles($scope);
@@ -537,7 +540,7 @@ module.directive('uiGrid',
537540
post: function ($scope, $elm, $attrs, uiGridCtrl) {
538541
$log.debug('ui-grid postlink');
539542

540-
uiGridCtrl.grid.gridWidth = $scope.gridWidth = $elm[0].clientWidth;
543+
uiGridCtrl.grid.gridWidth = $scope.gridWidth = gridUtil.elementWidth($elm);
541544
uiGridCtrl.grid.gridHeight = $scope.gridHeight = gridUtil.elementHeight($elm);
542545

543546
uiGridCtrl.refreshCanvas();
@@ -557,7 +560,7 @@ module.directive('uiGrid',
557560

558561
return {
559562
pre: function($scope, iElement) {
560-
$log.debug('uiGridCell pre-link');
563+
// $log.debug('uiGridCell pre-link');
561564
var html = $scope.col.cellTemplate.replace(uiGridConstants.COL_FIELD, 'row.entity.' + $scope.col.colDef.field);
562565

563566
// if ($scope.col.enableCellEdit) {
@@ -578,7 +581,7 @@ module.directive('uiGrid',
578581
iElement.append(cellElement);
579582
},
580583
post: function($scope, iElement) {
581-
$log.debug('uiGridCell post-link');
584+
// $log.debug('uiGridCell post-link');
582585
// if ($scope.enableCellSelection) {
583586
// $scope.domAccessProvider.selectionHandlers($scope, iElement);
584587
// }

src/js/core/services/ui-grid-util.js

+53-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ function getStyles (elem) {
66
return elem.ownerDocument.defaultView.getComputedStyle(elem, null);
77
}
88

9-
var rnumnonpx = new RegExp( "^(" + (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source + ")(?!px)[a-z%]+$", "i" );
9+
var rnumnonpx = new RegExp( "^(" + (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source + ")(?!px)[a-z%]+$", "i" ),
10+
// swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
11+
// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
12+
rdisplayswap = /^(block|none|table(?!-c[ea]).+)/,
13+
cssShow = { position: "absolute", visibility: "hidden", display: "block" };
1014

1115
function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
1216
var i = extra === ( isBorderBox ? 'border' : 'content' ) ?
@@ -307,6 +311,41 @@ module.service('gridUtil', ['$window', '$document', '$http', '$templateCache', f
307311

308312
},
309313

314+
swap: function( elem, options, callback, args ) {
315+
var ret, name,
316+
old = {};
317+
318+
// Remember the old values, and insert the new ones
319+
for ( name in options ) {
320+
old[ name ] = elem.style[ name ];
321+
elem.style[ name ] = options[ name ];
322+
}
323+
324+
ret = callback.apply( elem, args || [] );
325+
326+
// Revert the old values
327+
for ( name in options ) {
328+
elem.style[ name ] = old[ name ];
329+
}
330+
331+
return ret;
332+
},
333+
334+
fakeElement: function( elem, options, callback, args ) {
335+
var ret, name,
336+
newElement = angular.element(elem).clone()[0];
337+
338+
for ( name in options ) {
339+
newElement.style[ name ] = options[ name ];
340+
}
341+
342+
angular.element(document.body).append(newElement);
343+
344+
ret = callback.call( newElement, newElement );
345+
346+
return ret;
347+
},
348+
310349
/**
311350
* @ngdoc method
312351
* @name normalizeWheelEvent
@@ -413,8 +452,19 @@ module.service('gridUtil', ['$window', '$document', '$http', '$templateCache', f
413452
if (typeof(e.length) !== 'undefined' && e.length) {
414453
e = elem[0];
415454
}
416-
417-
return elem ? getWidthOrHeight( e, name, extra ) : null;
455+
456+
if (e) {
457+
// debugger;
458+
var styles = getStyles(e);
459+
return e.offsetWidth === 0 && rdisplayswap.test(styles.display) ?
460+
s.fakeElement(e, cssShow, function(newElm) {
461+
return getWidthOrHeight( newElm, name, extra );
462+
}) :
463+
getWidthOrHeight( e, name, extra );
464+
}
465+
else {
466+
return null;
467+
}
418468
};
419469

420470
s['outerElement' + capsName] = function (elem, margin) {

src/less/cell.less

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
.ui-grid-cell {
22
overflow: hidden;
3-
position: absolute;
4-
// top: 0;
5-
// bottom: 0;
3+
// position: absolute;
4+
position: relative;
5+
float: left;
66
background-color: inherit;
77
}
88

src/less/header.less

+12-1
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,21 @@
88
font-weight: bold;
99

1010
.gradient(#f3f3f3, #eee, #fff);
11+
12+
// &:before, &:after {
13+
// content:"";
14+
// display:table;
15+
// }
16+
17+
// &:after {
18+
// clear:both;
19+
// }
1120
}
1221

1322
.ui-grid-header-cell {
14-
position: absolute;
23+
// position: absolute;
24+
position: relative;
25+
float: left;
1526
top: 0;
1627
bottom: 0;
1728
background-color: inherit;

test/unit/services/ui-grid-util.spec.js

+17
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,23 @@ describe('ui.grid.util', function() {
113113

114114
expect(w).toEqual(300);
115115
});
116+
117+
it('should work with hidden element', function() {
118+
angular.element(elm).remove();
119+
120+
elm = document.createElement('div');
121+
elm.style.height = "300px";
122+
elm.style.width = "200px";
123+
elm.style.display = "none";
124+
document.body.appendChild(elm);
125+
126+
angular.element(elm).append('<div id="testelm" style="display: none">Test Test Test</div>');
127+
128+
var testelm = document.getElementById('testelm');
129+
var h = gridUtil.elementHeight(testelm);
130+
131+
expect(h).toBeGreaterThan(0);
132+
});
116133
});
117134

118135
describe('elementWidth()', function () {

0 commit comments

Comments
 (0)