40

I am using the Angular-Bootstrap Dropdown. I want to prevent it from closing on click until the user closes it intentionally.

Default state is: The Dropdown closes when clicking somewhere in the Document.

I identified the relevant lines of code: (Line 12, dropdown.js)

this.open = function( dropdownScope ) {
   if ( !openScope ) {
     $document.bind('click', closeDropdown); // line to unbind
     $document.bind('keydown', escapeKeyBind);
   }
}

You can find the full code here: Link to Github

I don't want to change the original sources of angular-bootstrap to keep my project open for updates.

My question:

How can i unbind an event bound by a Directive to the document in an Angular Controller?

ulilicht
  • 737
  • 1
  • 7
  • 18

9 Answers9

148

I solved this by adding the following to my drop down-menu. This prevents the drop down from closing unless you click on the tag that opens it

<ul class="dropdown-menu" ng-click="$event.stopPropagation()">
Dane
  • 1,501
  • 1
  • 10
  • 4
27

For those who are using Angular UI-Bootstrap 0.13.0 or later version, here is the cleaner way that states on the UI-Bootstrap documentation.

By default the dropdown will automatically close if any of its elements is clicked, you can change this behavior by setting the auto-close option as follows:

  • always - (Default) automatically closes the dropdown when any of its elements is clicked.

  • outsideClick - closes the dropdown automatically only when the user clicks any element outside the dropdown.

  • disabled - disables the auto close. You can then control the open/close status of the dropdown manually, by using is-open. Please notice that the dropdown will still close if the toggle is clicked, the esc key is pressed or another dropdown is open. The dropdown will no longer close on $locationChangeSuccess events.

Here is the link to the documentation: https://angular-ui.github.io/bootstrap/#/dropdown

Anthony Huang
  • 566
  • 6
  • 7
4

You can stop event from bubbling up in DOM Tree in angular 2 and above by adding event propagation. Ex: (click)="$event.stopPropagation()"

Ramki
  • 158
  • 6
3

This is another hack, but you could add a directive to stop the toggle event from propagating. For example something like this worked for my specific use case:

<div>
<div class="btn-group" dropdown is-open="status.isopen" ng-controller="DropDownCtrl">
  <button type="button" class="btn btn-primary dropdown-toggle" ng-disabled="disabled">
    Button dropdown <span class="caret"></span>
  </button>
  <ul class="dropdown-menu" role="menu">
    <li ng-click="goToPage('Action')">Action</li>
    <li disable-auto-close>Don't Dismiss</li>
    <li ng-click="goToPage('SomethingElse')">Something else here</li>
  </ul>
</div>

Adding this directive to an element should disable the auto close behavior:

angular.module('plunker', ['ui.bootstrap'])
.controller('DropDownCtrl', ['$scope', '$location',
function($scope, $location) {
  // Controller logic here
  $scope.goToPage = function(page) {
    console.log("Going to " + page + ". Dropdown should close");
    $location.path(page);
  };
}])
.directive('disableAutoClose', function() {
  // directive for disabling the default
  // close on 'click' behavior
  return {
        link: function($scope, $element) {
            $element.on('click', function($event) {
                console.log("Dropdown should not close");
                $event.stopPropagation();
            });
        }
    };
});

Plunker Example Here

Erik Hunter
  • 1,137
  • 2
  • 6
  • 9
  • Unfortunately I think it's a wrong solution, pal. The reason why your "Don't Auto Dismiss"
  • doesn't dismiss the dropdown should be that it does not `code`href="#"`code` attribute, while the rest all have.
  • – adam_0628 Aug 03 '14 at 05:59
  • good catch @adam_0628. I added that event.stopPropagation in the wrong spot. But the basic idea should work. You want to disable the click event of the element. You do that by stopping the event from propagating up the chain with '$event.stopPropagation();' I updated the code above as well as the plunkr. Hopefully this solution works for you – Erik Hunter Aug 04 '14 at 14:37