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

Commit

Permalink
fix(dropdown): unbind toggle element event on scope destroy
Browse files Browse the repository at this point in the history
Also, change the way disabled dropdownToggle is read from `attrs` instead of element property.

Closes #1867
Closes #1870
  • Loading branch information
bekos committed Feb 27, 2014
1 parent 93da30d commit 890e2d3
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 4 deletions.
3 changes: 2 additions & 1 deletion src/dropdown/docs/demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

<!-- Single button -->
<div class="btn-group" dropdown is-open="status.isopen">
<button type="button" class="btn btn-primary dropdown-toggle">
<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">
Expand Down Expand Up @@ -45,6 +45,7 @@
<hr />
<p>
<button type="button" class="btn btn-default btn-sm" ng-click="toggleDropdown($event)">Toggle button dropdown</button>
<button type="button" class="btn btn-warning btn-sm" ng-click="disabled = !disabled">Enable/Disable</button>
</p>

</div>
12 changes: 9 additions & 3 deletions src/dropdown/dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,22 +112,28 @@ angular.module('ui.bootstrap.dropdown', [])
return;
}

element.bind('click', function(event) {
var toggleDropdown = function(event) {
event.preventDefault();
event.stopPropagation();

if ( !element.hasClass('disabled') && !element.prop('disabled') ) {
if ( !element.hasClass('disabled') && !attrs.disabled ) {
scope.$apply(function() {
dropdownCtrl.toggle();
});
}
});
};

element.bind('click', toggleDropdown);

// WAI-ARIA
element.attr({ 'aria-haspopup': true, 'aria-expanded': false });
scope.$watch(dropdownCtrl.isOpen, function( isOpen ) {
element.attr('aria-expanded', !!isOpen);
});

scope.$on('$destroy', function() {
element.unbind('click', toggleDropdown);
});
}
};
});
29 changes: 29 additions & 0 deletions src/dropdown/test/dropdown.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,35 @@ describe('dropdownToggle', function() {
expect(elm.hasClass('open')).toBe(false);
});

it('should not toggle if the element has `ng-disabled` as true', function() {
$rootScope.isdisabled = true;
var elm = $compile('<li class="dropdown"><div ng-disabled="isdisabled" dropdown-toggle></div><ul><li>Hello</li></ul></li>')($rootScope);
$rootScope.$digest();
elm.find('div').click();
expect(elm.hasClass('open')).toBe(false);

$rootScope.isdisabled = false;
$rootScope.$digest();
elm.find('div').click();
expect(elm.hasClass('open')).toBe(true);
});

it('should unbind events on scope destroy', function() {
var $scope = $rootScope.$new();
var elm = $compile('<li class="dropdown"><button ng-disabled="isdisabled" dropdown-toggle></button><ul><li>Hello</li></ul></li>')($scope);
$scope.$digest();

var buttonEl = elm.find('button');
buttonEl.click();
expect(elm.hasClass('open')).toBe(true);
buttonEl.click();
expect(elm.hasClass('open')).toBe(false);

$scope.$destroy();
buttonEl.click();
expect(elm.hasClass('open')).toBe(false);
});

// issue 270
it('executes other document click events normally', function() {
var checkboxEl = $compile('<input type="checkbox" ng-click="clicked = true" />')($rootScope);
Expand Down

0 comments on commit 890e2d3

Please sign in to comment.