diff --git a/src/tooltip/tooltip.js b/src/tooltip/tooltip.js index 3176f96902..3a873bc86b 100644 --- a/src/tooltip/tooltip.js +++ b/src/tooltip/tooltip.js @@ -116,6 +116,7 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap var triggers = getTriggers( undefined ); var hasRegisteredTriggers = false; var hasEnableExp = angular.isDefined(attrs[prefix+'Enable']); + var position; // By default, the tooltip is not open. // TODO add ability to start tooltip opened @@ -147,77 +148,74 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap }); } - // Show the tooltip popup element. - function show() { - var position, - ttWidth, - ttHeight, + // Calculate tootip's position + function updatePosition() { + var ttWidth = tooltip.prop( 'offsetWidth' ), + ttHeight = tooltip.prop( 'offsetHeight' ), ttPosition; - - // Don't show empty tooltips. - if ( ! scope.tt_content ) { - return; - } - - // If there is a pending remove transition, we must cancel it, lest the - // tooltip be mysteriously removed. - if ( transitionTimeout ) { - $timeout.cancel( transitionTimeout ); - } - - // Set the initial positioning. - tooltip.css({ top: 0, left: 0, display: 'block' }); - - // Now we add it to the DOM because need some info about it. But it's not - // visible yet anyway. - if ( appendToBody ) { - $document.find( 'body' ).append( tooltip ); - } else { - element.after( tooltip ); - } - - // Get the position of the directive element. - position = appendToBody ? $position.offset( element ) : $position.position( element ); - - // Get the height and width of the tooltip so we can center it. - ttWidth = tooltip.prop( 'offsetWidth' ); - ttHeight = tooltip.prop( 'offsetHeight' ); // Calculate the tooltip's top and left coordinates to center it with // this directive. switch ( scope.tt_placement ) { case 'right': ttPosition = { - top: position.top + position.height / 2 - ttHeight / 2, - left: position.left + position.width + top: position.top + position.height / 2 - ttHeight / 2 + 'px', + left: position.left + position.width + 'px' }; break; case 'bottom': ttPosition = { - top: position.top + position.height, - left: position.left + position.width / 2 - ttWidth / 2 + top: position.top + position.height + 'px', + left: position.left + position.width / 2 - ttWidth / 2 + 'px' }; break; case 'left': ttPosition = { - top: position.top + position.height / 2 - ttHeight / 2, - left: position.left - ttWidth + top: position.top + position.height / 2 - ttHeight / 2 + 'px', + left: position.left - ttWidth + 'px' }; break; default: ttPosition = { - top: position.top - ttHeight, - left: position.left + position.width / 2 - ttWidth / 2 + top: position.top - ttHeight + 'px', + left: position.left + position.width / 2 - ttWidth / 2 + 'px' }; break; } - ttPosition.top += 'px'; - ttPosition.left += 'px'; - // Now set the calculated positioning. tooltip.css( ttPosition ); - + } + + // Show the tooltip popup element. + function show() { + // Don't show empty tooltips. + if ( ! scope.tt_content ) { + return; + } + + // If there is a pending remove transition, we must cancel it, lest the + // tooltip be mysteriously removed. + if ( transitionTimeout ) { + $timeout.cancel( transitionTimeout ); + } + + tooltip.css({ display: 'block' }); + + // Now we add it to the DOM because need some info about it. But it's not + // visible yet anyway. + if ( appendToBody ) { + $document.find( 'body' ).append( tooltip ); + } else { + element.after( tooltip ); + } + + // Get the position of the directive element. + position = appendToBody ? $position.offset( element ) : $position.position( element ); + + // Place tooltip + updatePosition(); + // And show the tooltip. scope.tt_isOpen = true; } @@ -248,8 +246,14 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap attrs.$observe( type, function ( val ) { scope.tt_content = val; - if (!val && scope.tt_isOpen ) { - hide(); + if (scope.tt_isOpen) { + if (!val) { + hide(); + } else { + // Wait for content to be set on the tooltip element and adjust position + // based on the new width/height and last known position of the directive element. + $timeout(updatePosition); + } } });