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

hide tooltips and popovers when a user clicks away (corrected) #4871

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/tooltip/docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ provided hide triggers:

- `mouseenter`: `mouseleave`
- `click`: `click`
- `outsideClick`: `outsideClick`
- `focus`: `blur`
- `none`: ``

The `outsideClick` trigger will cause the tooltip to toggle on click, and hide when anything else is clicked.

For any non-supported value, the trigger will be used to both show and hide the
tooltip. Using the 'none' trigger will disable the internal trigger(s), one can
then use the `tooltip-is-open` attribute exclusively to show and hide the tooltip.
Expand Down
25 changes: 25 additions & 0 deletions src/tooltip/test/tooltip.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,31 @@ describe('tooltip', function() {
elm.trigger('mouseenter');
expect(tooltipScope.isOpen).toBeFalsy();
}));

it('should toggle on click and hide when anything else is clicked when trigger is set to "outsideClick"', inject(function($compile, $document) {
elm = $compile(angular.element(
'<span uib-tooltip="tooltip text" tooltip-trigger="outsideClick">Selector Text</span>'
))(scope);
scope.$apply();
elmScope = elm.scope();
tooltipScope = elmScope.$$childTail;

// start off
expect(tooltipScope.isOpen).toBeFalsy();

// toggle
trigger(elm, 'click');
expect(tooltipScope.isOpen).toBeTruthy();
trigger(elm, 'click');
expect(tooltipScope.isOpen).toBeFalsy();

// click on, outsideClick off
trigger(elm, 'click');
expect(tooltipScope.isOpen).toBeTruthy();
angular.element($document[0].body).trigger('click');
tooltipScope.$digest();
expect(tooltipScope.isOpen).toBeFalsy();
}));
});

describe('with an append-to-body attribute', function() {
Expand Down
35 changes: 32 additions & 3 deletions src/tooltip/tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
var triggerMap = {
'mouseenter': 'mouseleave',
'click': 'click',
'outsideClick': 'outsideClick',
'focus': 'blur',
'none': ''
};
Expand Down Expand Up @@ -422,13 +423,37 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
}
}

// hide tooltips/popovers for outsideClick trigger
function bodyHideTooltipBind(e) {
if (ttScope === null || !ttScope.isOpen || tooltip === null) {
return;
}
// make sure the tooltip/popover link or tool tooltip/popover itself were not clicked
if (!element[0].contains(e.target) && !tooltip[0].contains(e.target)) {
hideTooltipBind();
}
}

var unregisterTriggers = function() {
triggers.show.forEach(function(trigger) {
element.unbind(trigger, showTooltipBind);
if (trigger === 'outsideClick') {
element[0].removeEventListener('click', toggleTooltipBind);
}
else
{
element[0].removeEventListener(trigger, showTooltipBind);
element[0].removeEventListener(trigger, toggleTooltipBind);
}
});
triggers.hide.forEach(function(trigger) {
trigger.split(' ').forEach(function(hideTrigger) {
element[0].removeEventListener(hideTrigger, hideTooltipBind);
if (trigger === 'outsideClick') {
$document[0].body.removeEventListener('click', bodyHideTooltipBind);
}
else
{
element[0].removeEventListener(hideTrigger, hideTooltipBind);
}
});
});
};
Expand All @@ -442,7 +467,11 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
if (triggers.show !== 'none') {
triggers.show.forEach(function(trigger, idx) {
// Using raw addEventListener due to jqLite/jQuery bug - #4060
if (trigger === triggers.hide[idx]) {
if (trigger === 'outsideClick') {
element[0].addEventListener('click', toggleTooltipBind);
$document[0].body.addEventListener('click', bodyHideTooltipBind);
}
else if (trigger === triggers.hide[idx]) {
element[0].addEventListener(trigger, toggleTooltipBind);
} else if (trigger) {
element[0].addEventListener(trigger, showTooltipBind);
Expand Down