Skip to content

Commit 0491c43

Browse files
committed
feat(a11y): Add option to control aria-labelledby attribute.
- Retains existing functionality with placeholder/input-id
1 parent a4cbd24 commit 0491c43

File tree

2 files changed

+66
-6
lines changed

2 files changed

+66
-6
lines changed

src/autocomplete/typeahead.js

+12-3
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,17 @@ function buildDom(options) {
544544
type: $input.attr('type')
545545
});
546546

547+
// Use ariaLabelledBy option if specified
548+
var ariaLabelledBy = options.ariaLabelledBy;
549+
if (ariaLabelledBy === false) {
550+
// If it is explicity false, null the field
551+
ariaLabelledBy = null;
552+
} else if (!ariaLabelledBy && $input.attr('placeholder')) {
553+
// If a placeholder is set, label this field with itself, which in this case,
554+
// is an explicit pointer to use the placeholder attribute value.
555+
ariaLabelledBy = $input.attr('id');
556+
}
557+
547558
$input
548559
.addClass(_.className(options.cssClasses.prefix, options.cssClasses.input, true))
549560
.attr({
@@ -562,9 +573,7 @@ function buildDom(options) {
562573
options.datasets[0] && options.datasets[0].displayKey ? 'both' : 'list'),
563574
// Indicates whether the dropdown it controls is currently expanded or collapsed
564575
'aria-expanded': 'false',
565-
// If a placeholder is set, label this field with itself, which in this case,
566-
// is an explicit pointer to use the placeholder attribute value.
567-
'aria-labelledby': ($input.attr('placeholder') ? $input.attr('id') : null),
576+
'aria-labelledby': ariaLabelledBy,
568577
// Explicitly point to the listbox,
569578
// which is a list of suggestions (aka options)
570579
'aria-owns': options.listboxId

test/unit/typeahead_spec.js

+54-3
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ describe('Typeahead', function() {
9494
var that = this;
9595
waitsForAndRuns(function() { return that.dropdown.close.calls.count(); }, done, 100);
9696
});
97-
9897
});
9998

10099
describe('when dropdown triggers suggestionClicked with undefined displayKey', function() {
@@ -871,17 +870,69 @@ describe('Typeahead', function() {
871870
});
872871

873872
describe('when set autoWidth option', function() {
874-
it ('should set default to true', function() {
873+
it('should set default to true', function() {
875874
this.dropdown.trigger('redrawn');
876875
expect(this.view.autoWidth).toBeTruthy();
877876
expect(/\d{3}px/.test(this.view.$node[0].style.width)).toBeTruthy();
878877
});
879878

880-
it ('should not put width style when autoWidth is false', function() {
879+
it('should not put width style when autoWidth is false', function() {
881880
this.view.autoWidth = false;
882881
this.dropdown.trigger('redrawn');
883882
expect(this.view.autoWidth).toBeFalsy();
884883
expect(this.view.$node[0].style.width).toBeFalsy();
885884
});
886885
});
886+
887+
describe('when ariaLabelledBy is set', function() {
888+
beforeEach(function() {
889+
this.view.destroy();
890+
});
891+
892+
describe('when set to a specific id', function() {
893+
it('should set aria-labelledby to the specified id', function() {
894+
this.view = new Typeahead({
895+
input: this.$input,
896+
ariaLabelledBy: 'custom-id-attr'
897+
});
898+
899+
expect(this.$input.attr('aria-labelledby')).toBe('custom-id-attr');
900+
});
901+
});
902+
903+
describe('when set to false', function() {
904+
it('should set aria-labelledby to null', function() {
905+
this.view = new Typeahead({
906+
input: this.$input,
907+
ariaLabelledBy: false
908+
});
909+
910+
expect(this.$input.attr('aria-labelledby')).toBeUndefined();
911+
});
912+
});
913+
914+
describe('when not set', function() {
915+
beforeEach(function() {
916+
this.$input.attr('id', 'custom-input-id');
917+
});
918+
919+
it('should set aria-labelledby to null if no placeholder specified', function() {
920+
this.view = new Typeahead({
921+
input: this.$input
922+
});
923+
924+
expect(this.$input.attr('aria-labelledby')).toBeUndefined();
925+
});
926+
927+
it('should set aria-labelledby to the input id if a placeholder is specified', function() {
928+
this.$input.attr('placeholder', 'custom placeholder');
929+
930+
this.view = new Typeahead({
931+
input: this.$input
932+
});
933+
934+
expect(this.$input.attr('aria-labelledby')).toBe('custom-input-id');
935+
});
936+
});
937+
});
887938
});

0 commit comments

Comments
 (0)