Skip to content
This repository has been archived by the owner on Oct 2, 2019. It is now read-only.

Commit

Permalink
fix(positioning): wait for animation to complete
Browse files Browse the repository at this point in the history
When calculating the dropdown position the height of the dropdown
needs to be known. When using ngAnimate the animation has not
finished by the time the height calculation is needed. This fix
extracts the positioning calculation out to a function that is
called after animation is done (or immediately when animation is
not in use).

Fixes #1593.
  • Loading branch information
darrinholst committed May 16, 2016
1 parent 2133f82 commit aa90dd8
Showing 1 changed file with 49 additions and 37 deletions.
86 changes: 49 additions & 37 deletions src/uiSelectDirective.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,57 +323,69 @@ uis.directive('uiSelect',

};

scope.calculateDropdownPos = function(){
var calculateDropdownPosAfterAnimation = function() {
// Delay positioning the dropdown until all choices have been added so its height is correct.
$timeout(function() {
if ($select.dropdownPosition === 'up') {
//Go UP
setDropdownPosUp();
} else {
//AUTO
element.removeClass(directionUpClassName);

var offset = uisOffset(element);
var offsetDropdown = uisOffset(dropdown);

//https://code.google.com/p/chromium/issues/detail?id=342307#c4
var scrollTop = $document[0].documentElement.scrollTop || $document[0].body.scrollTop; //To make it cross browser (blink, webkit, IE, Firefox).

// Determine if the direction of the dropdown needs to be changed.
if (offset.top + offset.height + offsetDropdown.height > scrollTop + $document[0].documentElement.clientHeight) {
//Go UP
setDropdownPosUp(offset, offsetDropdown);
}else{
//Go DOWN
setDropdownPosDown(offset, offsetDropdown);
}
}

// Display the dropdown once it has been positioned.
dropdown[0].style.opacity = 1;
});
};

scope.calculateDropdownPos = function() {
if ($select.open) {
dropdown = angular.element(element).querySelectorAll('.ui-select-dropdown');

if (dropdown.length === 0) {
return;
}

// Hide the dropdown so there is no flicker until $timeout is done executing.
dropdown[0].style.opacity = 0;

// Delay positioning the dropdown until all choices have been added so its height is correct.
$timeout(function(){

if ($select.dropdownPosition === 'up'){
//Go UP
setDropdownPosUp();

}else{ //AUTO
if (!uisOffset(dropdown).height && $select.$animate && $select.$animate.on && $select.$animate.enabled(dropdown)) {
var needsCalculated = true;

element.removeClass(directionUpClassName);

var offset = uisOffset(element);
var offsetDropdown = uisOffset(dropdown);

//https://code.google.com/p/chromium/issues/detail?id=342307#c4
var scrollTop = $document[0].documentElement.scrollTop || $document[0].body.scrollTop; //To make it cross browser (blink, webkit, IE, Firefox).

// Determine if the direction of the dropdown needs to be changed.
if (offset.top + offset.height + offsetDropdown.height > scrollTop + $document[0].documentElement.clientHeight) {
//Go UP
setDropdownPosUp(offset, offsetDropdown);
}else{
//Go DOWN
setDropdownPosDown(offset, offsetDropdown);
$select.$animate.on('enter', dropdown, function (elem, phase) {
if (phase === 'close' && needsCalculated) {
calculateDropdownPosAfterAnimation();
needsCalculated = false;
}

}

// Display the dropdown once it has been positioned.
dropdown[0].style.opacity = 1;
});
});
} else {
calculateDropdownPosAfterAnimation();
}
} else {
if (dropdown === null || dropdown.length === 0) {
return;
}
if (dropdown === null || dropdown.length === 0) {
return;
}

// Reset the position of the dropdown.
dropdown[0].style.position = '';
dropdown[0].style.top = '';
element.removeClass(directionUpClassName);
// Reset the position of the dropdown.
dropdown[0].style.position = '';
dropdown[0].style.top = '';
element.removeClass(directionUpClassName);
}
};
};
Expand Down

0 comments on commit aa90dd8

Please sign in to comment.