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

Commit

Permalink
feat(tooltip): add outsideClick trigger
Browse files Browse the repository at this point in the history
- Add `outsideClick` trigger support, which allows dismissal of the tooltip/popover on click of any element outside of the tooltip/popover

Closes #4419
Closes #4871
  • Loading branch information
SystemDisc authored and wesleycho committed Nov 10, 2015
1 parent 3ca8b88 commit 8737303
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 3 deletions.
3 changes: 3 additions & 0 deletions src/tooltip/docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,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 @@ -596,6 +596,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
30 changes: 27 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 @@ -438,13 +439,33 @@ angular.module('ui.bootstrap.tooltip', ['ui.bootstrap.position', 'ui.bootstrap.s
}
}

// hide tooltips/popovers for outsideClick trigger
function bodyHideTooltipBind(e) {
if (!ttScope || !ttScope.isOpen || !tooltip) {
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].removeEventListener('click', bodyHideTooltipBind);
} else {
element[0].removeEventListener(hideTrigger, hideTooltipBind);
}
});
});
};
Expand All @@ -458,7 +479,10 @@ 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].addEventListener('click', bodyHideTooltipBind);
} else if (trigger === triggers.hide[idx]) {
element[0].addEventListener(trigger, toggleTooltipBind);
} else if (trigger) {
element[0].addEventListener(trigger, showTooltipBind);
Expand Down

0 comments on commit 8737303

Please sign in to comment.