Skip to content

Commit

Permalink
Fixes tooltip misplacements in scrollable viewports with auto positio…
Browse files Browse the repository at this point in the history
…ning

Fixes #14756.
Closes #14767.
  • Loading branch information
saranya.r authored and hnrch02 committed Oct 22, 2014
1 parent 2bc5277 commit e2cfbd5
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 4 deletions.
104 changes: 104 additions & 0 deletions js/tests/unit/tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,110 @@ $(function () {
$styles.remove()
})

test('should display the tip on top whenever scrollable viewport has enough room if the given placement is "auto top"', function () {
var styles = '<style>'
+ '#scrollable-div { height: 200px; overflow: auto; }'
+ '.tooltip-item { margin: 200px 0 400px; width: 150px; }'
+ '</style>'
var $styles = $(styles).appendTo('head')

var $container = $('<div id="scrollable-div"/>').appendTo('#qunit-fixture')
var $target = $('<div rel="tooltip" title="tip" class="tooltip-item">Tooltip Item</div>')
.appendTo($container)
.bootstrapTooltip({
placement: 'top auto',
viewport: '#scrollable-div'
})

$('#scrollable-div').scrollTop(100)

$target.bootstrapTooltip('show')
ok($('.tooltip').is('.fade.top.in'), 'has correct classes applied')

$target.bootstrapTooltip('hide')
equal($('.tooltip').length, 0, 'tooltip removed from dom')

$styles.remove()
})

test('should display the tip on bottom whenever scrollable viewport doesn\'t have enough room if the given placement is "auto top"', function () {
var styles = '<style>'
+ '#scrollable-div { height: 200px; overflow: auto; }'
+ '.tooltip-item { margin: 200px 0 400px; width: 150px; }'
+ '</style>'
var $styles = $(styles).appendTo('head')

var $container = $('<div id="scrollable-div"/>').appendTo('#qunit-fixture')
var $target = $('<div rel="tooltip" title="tip" class="tooltip-item">Tooltip Item</div>')
.appendTo($container)
.bootstrapTooltip({
placement: 'top auto',
viewport: '#scrollable-div'
})

$('#scrollable-div').scrollTop(200)

$target.bootstrapTooltip('show')
ok($('.tooltip').is('.fade.bottom.in'), 'has correct classes applied')

$target.bootstrapTooltip('hide')
equal($('.tooltip').length, 0, 'tooltip removed from dom')

$styles.remove()
})

test('should display the tip on bottom whenever scrollable viewport has enough room if the given placement is "auto bottom"', function () {
var styles = '<style>'
+ '#scrollable-div { height: 200px; overflow: auto; }'
+ '.tooltip-item { margin: 200px 0 400px; width: 150px; }'
+ '</style>'
var $styles = $(styles).appendTo('head')

var $container = $('<div id="scrollable-div"/>').appendTo('#qunit-fixture')
var $target = $('<div rel="tooltip" title="tip" class="tooltip-item">Tooltip Item</div>')
.appendTo($container)
.bootstrapTooltip({
placement: 'bottom auto',
viewport: '#scrollable-div'
})

$('#scrollable-div').scrollTop(200)

$target.bootstrapTooltip('show')
ok($('.tooltip').is('.fade.bottom.in'), 'has correct classes applied')

$target.bootstrapTooltip('hide')
equal($('.tooltip').length, 0, 'tooltip removed from dom')

$styles.remove()
})

test('should display the tip on top whenever scrollable viewport doesn\'t have enough room if the given placement is "auto bottom"', function () {
var styles = '<style>'
+ '#scrollable-div { height: 200px; overflow: auto; }'
+ '.tooltip-item { margin-top: 400px; width: 150px; }'
+ '</style>'
var $styles = $(styles).appendTo('head')

var $container = $('<div id="scrollable-div"/>').appendTo('#qunit-fixture')
var $target = $('<div rel="tooltip" title="tip" class="tooltip-item">Tooltip Item</div>')
.appendTo($container)
.bootstrapTooltip({
placement: 'bottom auto',
viewport: '#scrollable-div'
})

$('#scrollable-div').scrollTop(400)

$target.bootstrapTooltip('show')
ok($('.tooltip').is('.fade.top.in'), 'has correct classes applied')

$target.bootstrapTooltip('hide')
equal($('.tooltip').length, 0, 'tooltip removed from dom')

$styles.remove()
})

test('should adjust the tip\'s top position when up against the top of the viewport', function () {
var styles = '<style>'
+ '.tooltip .tooltip-inner { width: 200px; height: 200px; max-width: none; }'
Expand Down
8 changes: 4 additions & 4 deletions js/tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,10 @@
var $container = this.options.container ? $(this.options.container) : this.$element.parent()
var containerDim = this.getPosition($container)

placement = placement == 'bottom' && pos.top + pos.height + actualHeight - containerDim.scroll > containerDim.height ? 'top' :
placement == 'top' && pos.top - containerDim.scroll - actualHeight < containerDim.top ? 'bottom' :
placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' :
placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' :
placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' :
placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' :
placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' :
placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' :
placement

$tip
Expand Down

1 comment on commit e2cfbd5

@ismyrnow
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just want to give a big thank you for this commit. Saved me from building this logic into my app. 👍

Please sign in to comment.