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

Commit 890e2d3

Browse files
committed
fix(dropdown): unbind toggle element event on scope destroy
Also, change the way disabled dropdownToggle is read from `attrs` instead of element property. Closes #1867 Closes #1870
1 parent 93da30d commit 890e2d3

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

src/dropdown/docs/demo.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
<!-- Single button -->
1616
<div class="btn-group" dropdown is-open="status.isopen">
17-
<button type="button" class="btn btn-primary dropdown-toggle">
17+
<button type="button" class="btn btn-primary dropdown-toggle" ng-disabled="disabled">
1818
Button dropdown <span class="caret"></span>
1919
</button>
2020
<ul class="dropdown-menu" role="menu">
@@ -45,6 +45,7 @@
4545
<hr />
4646
<p>
4747
<button type="button" class="btn btn-default btn-sm" ng-click="toggleDropdown($event)">Toggle button dropdown</button>
48+
<button type="button" class="btn btn-warning btn-sm" ng-click="disabled = !disabled">Enable/Disable</button>
4849
</p>
4950

5051
</div>

src/dropdown/dropdown.js

+9-3
Original file line numberDiff line numberDiff line change
@@ -112,22 +112,28 @@ angular.module('ui.bootstrap.dropdown', [])
112112
return;
113113
}
114114

115-
element.bind('click', function(event) {
115+
var toggleDropdown = function(event) {
116116
event.preventDefault();
117117
event.stopPropagation();
118118

119-
if ( !element.hasClass('disabled') && !element.prop('disabled') ) {
119+
if ( !element.hasClass('disabled') && !attrs.disabled ) {
120120
scope.$apply(function() {
121121
dropdownCtrl.toggle();
122122
});
123123
}
124-
});
124+
};
125+
126+
element.bind('click', toggleDropdown);
125127

126128
// WAI-ARIA
127129
element.attr({ 'aria-haspopup': true, 'aria-expanded': false });
128130
scope.$watch(dropdownCtrl.isOpen, function( isOpen ) {
129131
element.attr('aria-expanded', !!isOpen);
130132
});
133+
134+
scope.$on('$destroy', function() {
135+
element.unbind('click', toggleDropdown);
136+
});
131137
}
132138
};
133139
});

src/dropdown/test/dropdown.spec.js

+29
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,35 @@ describe('dropdownToggle', function() {
9191
expect(elm.hasClass('open')).toBe(false);
9292
});
9393

94+
it('should not toggle if the element has `ng-disabled` as true', function() {
95+
$rootScope.isdisabled = true;
96+
var elm = $compile('<li class="dropdown"><div ng-disabled="isdisabled" dropdown-toggle></div><ul><li>Hello</li></ul></li>')($rootScope);
97+
$rootScope.$digest();
98+
elm.find('div').click();
99+
expect(elm.hasClass('open')).toBe(false);
100+
101+
$rootScope.isdisabled = false;
102+
$rootScope.$digest();
103+
elm.find('div').click();
104+
expect(elm.hasClass('open')).toBe(true);
105+
});
106+
107+
it('should unbind events on scope destroy', function() {
108+
var $scope = $rootScope.$new();
109+
var elm = $compile('<li class="dropdown"><button ng-disabled="isdisabled" dropdown-toggle></button><ul><li>Hello</li></ul></li>')($scope);
110+
$scope.$digest();
111+
112+
var buttonEl = elm.find('button');
113+
buttonEl.click();
114+
expect(elm.hasClass('open')).toBe(true);
115+
buttonEl.click();
116+
expect(elm.hasClass('open')).toBe(false);
117+
118+
$scope.$destroy();
119+
buttonEl.click();
120+
expect(elm.hasClass('open')).toBe(false);
121+
});
122+
94123
// issue 270
95124
it('executes other document click events normally', function() {
96125
var checkboxEl = $compile('<input type="checkbox" ng-click="clicked = true" />')($rootScope);

0 commit comments

Comments
 (0)