diff --git a/src/uiSelectDirective.js b/src/uiSelectDirective.js index fc6cc4138..a1df3fcff 100644 --- a/src/uiSelectDirective.js +++ b/src/uiSelectDirective.js @@ -254,42 +254,52 @@ uis.directive('uiSelect', directionUpClassName = 'direction-up'; // Support changing the direction of the dropdown if there isn't enough space to render it. - scope.$watch('$select.open', function(isOpen) { - if (isOpen) { + function detectDirection() { + if (scope.$select.open) { dropdown = angular.element(element).querySelectorAll('.ui-select-dropdown'); if (dropdown === null) { return; } + var dropdownStyle = dropdown[0].style; + // Hide the dropdown so there is no flicker until $timeout is done executing. - dropdown[0].style.visibility = 'hidden'; + dropdownStyle.visibility = 'hidden'; // Delay positioning the dropdown until all choices have been added so its height is correct. $timeout(function(){ var offset = uisOffset(element); var offsetDropdown = uisOffset(dropdown); + // If dropdown is already opened above input field then + // update its top position according to dropdown height. + if (angular.element(element).hasClass(directionUpClassName)) { + dropdownStyle.top = (offsetDropdown.height * -1) + 'px'; // Determine if the direction of the dropdown needs to be changed. - if (offset.top + offset.height + offsetDropdown.height > $document[0].documentElement.scrollTop + $document[0].documentElement.clientHeight) { - dropdown[0].style.position = 'absolute'; - dropdown[0].style.top = (offsetDropdown.height * -1) + 'px'; + } else if (offset.top + offset.height + offsetDropdown.height > $document[0].documentElement.scrollTop + $document[0].documentElement.clientHeight) { + dropdownStyle.position = 'absolute'; + dropdownStyle.top = (offsetDropdown.height * -1) + 'px'; element.addClass(directionUpClassName); + } else { + dropdownStyle.position = ''; + dropdownStyle.top = ''; + element.removeClass(directionUpClassName); } // Display the dropdown once it has been positioned. - dropdown[0].style.visibility = ''; + dropdownStyle.visibility = ''; }); - } else { - if (dropdown === null) { - return; - } - - // Reset the position of the dropdown. - dropdown[0].style.position = ''; - dropdown[0].style.top = ''; - element.removeClass(directionUpClassName); + } else if (dropdown !== null) { + // Reset the position of the dropdown. + dropdown[0].style.position = ''; + dropdown[0].style.top = ''; + element.removeClass(directionUpClassName); } - }); + } + + scope.$watch('$select.open', detectDirection); + scope.$watch('$select.search', detectDirection); + scope.$watch('$select.selected', detectDirection); }; } };