Close all Angular JS Bootstrap popovers with a click anywhere on the screen?

I use Angular directives to bootstrap.

I have a popover, as in their example:

<button popover="Hello, World!" popover-title="Title" class="btn btn-default ng-scope">Dynamic Popover</button> 

It closes when you press the button again. I would like to close it - and any other open popovers - when the user clicks anywhere.

I do not see a built-in way to do this.

+7
javascript jquery angularjs twitter-bootstrap
source share
8 answers
 angular.element(document.body).bind('click', function (e) { var popups = document.querySelectorAll('.popover'); if(popups) { for(var i=0; i<popups.length; i++) { var popup = popups[i]; var popupElement = angular.element(popup); if(popupElement[0].previousSibling!=e.target){ popupElement.scope().$parent.isOpen=false; popupElement.remove(); } } } }); 
+9
source share

This function request is tracked ( https://github.com/angular-ui/bootstrap/issues/618 ). Similar to aet's answer, you can do what is recommended in the function request, as a workaround:

 $('body').on('click', function (e) { $('*[popover]').each(function () { //Only do this for all popovers other than the current one that cause this event if (!($(this).is(e.target) || $(this).has(e.target).length > 0) && $(this).siblings('.popover').length !== 0 && $(this).siblings('.popover').has(e.target).length === 0) { //Remove the popover element from the DOM $(this).siblings('.popover').remove(); //Set the state of the popover in the scope to reflect this angular.element(this).scope().tt_isOpen = false; } }); }); 

(source: vchatterji comment in function request mentioned above)

The function request also has a non-jQuery solution, as well as this plnkr: http://plnkr.co/edit/fhsy4V

+2
source share
  angular.element(document.body).bind('click', function (e) { var popups = document.querySelectorAll('.popover'); if (popups) { for (var i = 0; i < popups.length; i++) { var popup = popups[i]; var popupElement = angular.element(popup); console.log(2); if (popupElement[0].previousSibling != e.target) { popupElement.scope().$parent.isOpen = false; popupElement.scope().$parent.$apply(); } } } }); 
+1
source share

One idea is that you can change the trigger to use mouse on and off, which will only display one pop-up at a time. The following is an example:

 <button popover="I appeared on mouse enter!" popover-trigger="mouseenter" class="btn btn-default" popover-placement="bottom" >Hello World</button> 

You can see this worker in this plunker . You can find a complete list of tooltip triggers on the angular boot site (tooltips and popovers have the same startup options). Good luck

0
source share

What you say is the default settings for popover, but you can control it with the trigger function by placing the blur in the second argument of the trigger, like this popover-trigger="{mouseenter:blur}"

0
source share

There was one and the same requirement, and that’s how we did it: First, we modified the bootstrap in the tooltip link function:

 if (prefix === "popover") { element.addClass('popover-link'); } 

Then we start the click handler on the body like this:

 $('body').on('click', function(e) { var clickedOutside = true; // popover-link comes from our modified ui-bootstrap-tpls $('.popover-link').each(function() { if ($(this).is(e.target) || $(this).has(e.target).length) { clickedOutside = false; return false; } }); if ($('.popover').has(e.target).length) { clickedOutside = false; } if (clickedOutside) { $('.popover').prev().click(); } }); 
0
source share

I use the code below for the same

  angular.element(document.body).popover({ selector: '[rel=popover]', trigger: "click" }).on("show.bs.popover", function(e){ angular.element("[rel=popover]").not(e.target).popover("destroy"); angular.element(".popover").remove(); }); 
0
source share

Thanks, Lauren Camtreher, it worked.

Your code is the only one that also triggers a state change in the area.

Only configured so that if you click on popover, the latter will close.

I mixed your code and now it also works if you click inside a popover.

Regardless of whether the system runs through popover-template,

To make it recognizable with a popover-template popup window, I used the popover-body and popover-title classes corresponding to the header and body of the popover created using the template and making sure that it points directly to them in the code:

 angular.element(document.body).bind('click', function (e) { var popups = document.querySelectorAll('.popover'); if(popups) { for(var i=0; i<popups.length; i++) { var popup = popups[i]; var popupElement = angular.element(popup); var content; var arrow; if(popupElement.next()) { //The following is the content child in the popovers first sibling // For the classic popover with Angularjs Ui Bootstrap content = popupElement[0].querySelector('.popover-content'); // For the templating popover (popover-template attrib) with Angularjs Ui Bootstrap bodytempl = popupElement[0].querySelector('.popover-body'); headertempl= popupElement[0].querySelector('.popover-title'); //The following is the arrow child in the popovers first sibling // For both cases. arrow = popupElement[0].querySelector('.arrow'); } if(popupElement[0].previousSibling!=e.target && e.target != content && e.target != arrow && e.target != bodytempl && e.target != headertempl){ popupElement.scope().$parent.isOpen=false; popupElement.remove(); } } } }); 

Ever had a good day, thanks Lauren, thanks AngularJS, thanks so many stack families!

Updated:

I updated all adding an additional control. Elements inside the popover were excluded from control (for example, the image inserted into the body of the popover.). Then click on the same closed.

I used the Node.contains API command integrated into a function that returns true or false.

Now, with any element placed inside, start the control and save the postcard if you click inside:

 // function for checkparent with Node.contains function check(parentNode, childNode) { if('contains' in parentNode) { return parentNode.contains(childNode); } else { return parentNode.compareDocumentPosition(childNode) % 16; }} angular.element(document.body).bind('click', function (e) { var popups = document.querySelectorAll('.popover'); if(popups) { for(var i=0; i<popups.length; i++) { var popup = popups[i]; var popupElement = angular.element(popup); var content; var arrow; if(popupElement.next()) { //The following is the content child in the popovers first sibling // For the classic popover with Angularjs Ui Bootstrap content = popupElement[0].querySelector('.popover-content'); // For the templating popover (popover-template attrib) with Angularjs Ui Bootstrap bodytempl = popupElement[0].querySelector('.popover-body'); headertempl= popupElement[0].querySelector('.popover-title'); //The following is the arrow child in the popovers first sibling // For both cases. arrow = popupElement[0].querySelector('.arrow'); } var checkel= check(content,e.target); if(popupElement[0].previousSibling!=e.target && e.target != content && e.target != arrow && e.target != bodytempl && e.target != headertempl&& checkel == false){ popupElement.scope().$parent.isOpen=false; popupElement.remove(); } } } }); 
-2
source share

All Articles