Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 944c150

Browse files
committed
fix(ngAria): correctly set "checked" attr for checkboxes and radios
Make sure the checked attribute is set correctly for: - checkboxes with string and integer models using ngTrueValue / ngFalseValue - radios with integer models - radios with boolean models using ngValue Fixes #10389 Fixes #10212
1 parent d8dc53d commit 944c150

File tree

2 files changed

+57
-3
lines changed

2 files changed

+57
-3
lines changed

src/ngAria/aria.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ function $AriaProvider() {
129129
* @name $aria
130130
*
131131
* @description
132+
* @priority 200
132133
*
133134
* The $aria service contains helper methods for applying common
134135
* [ARIA](http://www.w3.org/TR/wai-aria/) attributes to HTML directives.
@@ -205,6 +206,7 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
205206
return {
206207
restrict: 'A',
207208
require: '?ngModel',
209+
priority: 200, //Make sure watches are fired after any other directives that affect the ngModel value
208210
link: function(scope, elem, attr, ngModel) {
209211
var shape = getShape(attr, elem);
210212
var needsTabIndex = shouldAttachAttr('tabindex', 'tabindex', elem);
@@ -217,19 +219,19 @@ ngAriaModule.directive('ngShow', ['$aria', function($aria) {
217219
if (needsTabIndex) {
218220
needsTabIndex = false;
219221
return function ngAriaRadioReaction(newVal) {
220-
var boolVal = newVal === attr.value;
222+
var boolVal = (attr.value == ngModel.$viewValue);
221223
elem.attr('aria-checked', boolVal);
222224
elem.attr('tabindex', 0 - !boolVal);
223225
};
224226
} else {
225227
return function ngAriaRadioReaction(newVal) {
226-
elem.attr('aria-checked', newVal === attr.value);
228+
elem.attr('aria-checked', (attr.value == ngModel.$viewValue));
227229
};
228230
}
229231
}
230232

231233
function ngAriaCheckboxReaction(newVal) {
232-
elem.attr('aria-checked', !!newVal);
234+
elem.attr('aria-checked', !ngModel.$isEmpty(ngModel.$viewValue));
233235
}
234236

235237
switch (shape) {

test/ngAria/ariaSpec.js

+52
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,28 @@ describe('$aria', function() {
8585
expect(element.attr('aria-checked')).toBe('false');
8686
});
8787

88+
it('should handle checkbox with string model values using ng(True|False)Value', function() {
89+
var element = $compile('<input type="checkbox" ng-model="val" ng-true-value="\'yes\'" ' +
90+
'ng-false-value="\'no\'">'
91+
)(scope);
92+
93+
scope.$apply('val="yes"');
94+
expect(element.eq(0).attr('aria-checked')).toBe('true');
95+
96+
scope.$apply('val="no"');
97+
expect(element.eq(0).attr('aria-checked')).toBe('false');
98+
});
99+
100+
it('should handle checkbox with integer model values using ngTrueValue', function() {
101+
var element = $compile('<input type="checkbox" ng-model="val" ng-true-value="0">')(scope);
102+
103+
scope.$apply('val=0');
104+
expect(element.eq(0).attr('aria-checked')).toBe('true');
105+
106+
scope.$apply('val=1');
107+
expect(element.eq(0).attr('aria-checked')).toBe('false');
108+
});
109+
88110
it('should attach itself to input type="radio"', function() {
89111
var element = $compile('<input type="radio" ng-model="val" value="one">' +
90112
'<input type="radio" ng-model="val" value="two">')(scope);
@@ -98,6 +120,36 @@ describe('$aria', function() {
98120
expect(element.eq(1).attr('aria-checked')).toBe('true');
99121
});
100122

123+
it('should handle radios with integer model values', function() {
124+
var element = $compile('<input type="radio" ng-model="val" value="0">' +
125+
'<input type="radio" ng-model="val" value="1">')(scope);
126+
127+
scope.$apply('val=0');
128+
expect(element.eq(0).attr('aria-checked')).toBe('true');
129+
expect(element.eq(1).attr('aria-checked')).toBe('false');
130+
131+
scope.$apply('val=1');
132+
expect(element.eq(0).attr('aria-checked')).toBe('false');
133+
expect(element.eq(1).attr('aria-checked')).toBe('true');
134+
});
135+
136+
it('should handle radios with boolean model values using ngValue', function() {
137+
var element = $compile('<input type="radio" ng-model="val" ng-value="valExp">' +
138+
'<input type="radio" ng-model="val" ng-value="valExp2">')(scope);
139+
140+
scope.$apply(function() {
141+
scope.valExp = true;
142+
scope.valExp2 = false;
143+
scope.val = true;
144+
});
145+
expect(element.eq(0).attr('aria-checked')).toBe('true');
146+
expect(element.eq(1).attr('aria-checked')).toBe('false');
147+
148+
scope.$apply('val = false');
149+
expect(element.eq(0).attr('aria-checked')).toBe('false');
150+
expect(element.eq(1).attr('aria-checked')).toBe('true');
151+
});
152+
101153
it('should attach itself to role="radio"', function() {
102154
scope.$apply("val = 'one'");
103155
compileInput('<div role="radio" ng-model="val" value="{{val}}"></div>');

0 commit comments

Comments
 (0)