Skip to content

Commit 28c56e7

Browse files
committed
Better accessibility for multiple select boxes
1 parent cee8c18 commit 28c56e7

9 files changed

Lines changed: 168 additions & 158 deletions

File tree

dist/js/select2.amd.full.js

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -570,11 +570,31 @@ define('select2/selection/base',[
570570
BaseSelection.prototype.bind = function (container, $container) {
571571
var self = this;
572572

573+
var id = container.id + '-container';
574+
var resultsId = container.id + '-results';
575+
576+
this.$selection.attr('aria-owns', resultsId);
577+
578+
this.$selection.on('keydown', function (evt) {
579+
self.trigger('keypress', evt);
580+
581+
if (evt.which === KEYS.SPACE) {
582+
evt.preventDefault();
583+
}
584+
});
585+
586+
container.on('results:focus', function (params) {
587+
self.$selection.attr('aria-activedescendant', params.data._resultId);
588+
});
589+
573590
container.on('selection:update', function (params) {
574591
self.update(params.data);
575592
});
576593

577594
container.on('open', function () {
595+
// When the dropdown is open, aria-expanded="true"
596+
self.$selection.attr('aria-expanded', 'true');
597+
578598
$(document.body).on('mousedown.select2.' + container.id, function (e) {
579599
var $target = $(e.target);
580600

@@ -594,10 +614,16 @@ define('select2/selection/base',[
594614
$element.select2('close');
595615
});
596616
});
617+
});
597618

598-
container.on('close', function () {
599-
$(document.body).off('mousedown.select2.' + container.id);
600-
});
619+
container.on('close', function () {
620+
// When the dropdown is closed, aria-expanded="false"
621+
self.$selection.attr('aria-expanded', 'false');
622+
self.$selection.removeAttr('aria-activedescendant');
623+
624+
self.$selection.focus();
625+
626+
$(document.body).off('mousedown.select2.' + container.id);
601627
});
602628
};
603629

@@ -685,11 +711,9 @@ define('select2/selection/single',[
685711
SingleSelection.__super__.bind.apply(this, arguments);
686712

687713
var id = container.id + '-container';
688-
var resultsId = container.id + '-results';
689714

690715
this.$selection.find('.rendered-selection').attr('id', id);
691716
this.$selection.attr('aria-labelledby', id);
692-
this.$selection.attr('aria-owns', resultsId);
693717

694718
this.$selection.on('mousedown', function (evt) {
695719
// Only respond to left clicks
@@ -702,19 +726,6 @@ define('select2/selection/single',[
702726
});
703727
});
704728

705-
container.on('open', function () {
706-
// When the dropdown is open, aria-expanded="true"
707-
self.$selection.attr('aria-expanded', 'true');
708-
});
709-
710-
container.on('close', function () {
711-
// When the dropdown is closed, aria-expanded="false"
712-
self.$selection.attr('aria-expanded', 'false');
713-
self.$selection.removeAttr('aria-activedescendant');
714-
715-
self.$selection.focus();
716-
});
717-
718729
this.$selection.on('focus', function (evt) {
719730
// User focuses on the container
720731
});
@@ -723,18 +734,6 @@ define('select2/selection/single',[
723734
// User exits the container
724735
});
725736

726-
this.$selection.on('keydown', function (evt) {
727-
self.trigger('keypress', evt);
728-
729-
if (evt.which === KEYS.SPACE) {
730-
evt.preventDefault();
731-
}
732-
});
733-
734-
container.on('results:focus', function (params) {
735-
self.$selection.attr('aria-activedescendant', params.data._resultId);
736-
});
737-
738737
container.on('selection:update', function (params) {
739738
self.update(params.data);
740739
});
@@ -782,11 +781,14 @@ define('select2/selection/multiple',[
782781

783782
MultipleSelection.prototype.render = function () {
784783
var $selection = $(
785-
'<span class="multiple-select">' +
784+
'<span class="multiple-select" tabindex="0" role="combobox" ' +
785+
'aria-autocomplete="list" aria-haspopup="true" aria-expanded="false">' +
786786
'<ul class="rendered-selection"></ul>' +
787787
'</span>'
788788
);
789789

790+
$selection.attr('title', this.$element.attr('title'));
791+
790792
this.$selection = $selection;
791793

792794
return $selection;

dist/js/select2.amd.js

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -570,11 +570,31 @@ define('select2/selection/base',[
570570
BaseSelection.prototype.bind = function (container, $container) {
571571
var self = this;
572572

573+
var id = container.id + '-container';
574+
var resultsId = container.id + '-results';
575+
576+
this.$selection.attr('aria-owns', resultsId);
577+
578+
this.$selection.on('keydown', function (evt) {
579+
self.trigger('keypress', evt);
580+
581+
if (evt.which === KEYS.SPACE) {
582+
evt.preventDefault();
583+
}
584+
});
585+
586+
container.on('results:focus', function (params) {
587+
self.$selection.attr('aria-activedescendant', params.data._resultId);
588+
});
589+
573590
container.on('selection:update', function (params) {
574591
self.update(params.data);
575592
});
576593

577594
container.on('open', function () {
595+
// When the dropdown is open, aria-expanded="true"
596+
self.$selection.attr('aria-expanded', 'true');
597+
578598
$(document.body).on('mousedown.select2.' + container.id, function (e) {
579599
var $target = $(e.target);
580600

@@ -594,10 +614,16 @@ define('select2/selection/base',[
594614
$element.select2('close');
595615
});
596616
});
617+
});
597618

598-
container.on('close', function () {
599-
$(document.body).off('mousedown.select2.' + container.id);
600-
});
619+
container.on('close', function () {
620+
// When the dropdown is closed, aria-expanded="false"
621+
self.$selection.attr('aria-expanded', 'false');
622+
self.$selection.removeAttr('aria-activedescendant');
623+
624+
self.$selection.focus();
625+
626+
$(document.body).off('mousedown.select2.' + container.id);
601627
});
602628
};
603629

@@ -685,11 +711,9 @@ define('select2/selection/single',[
685711
SingleSelection.__super__.bind.apply(this, arguments);
686712

687713
var id = container.id + '-container';
688-
var resultsId = container.id + '-results';
689714

690715
this.$selection.find('.rendered-selection').attr('id', id);
691716
this.$selection.attr('aria-labelledby', id);
692-
this.$selection.attr('aria-owns', resultsId);
693717

694718
this.$selection.on('mousedown', function (evt) {
695719
// Only respond to left clicks
@@ -702,19 +726,6 @@ define('select2/selection/single',[
702726
});
703727
});
704728

705-
container.on('open', function () {
706-
// When the dropdown is open, aria-expanded="true"
707-
self.$selection.attr('aria-expanded', 'true');
708-
});
709-
710-
container.on('close', function () {
711-
// When the dropdown is closed, aria-expanded="false"
712-
self.$selection.attr('aria-expanded', 'false');
713-
self.$selection.removeAttr('aria-activedescendant');
714-
715-
self.$selection.focus();
716-
});
717-
718729
this.$selection.on('focus', function (evt) {
719730
// User focuses on the container
720731
});
@@ -723,18 +734,6 @@ define('select2/selection/single',[
723734
// User exits the container
724735
});
725736

726-
this.$selection.on('keydown', function (evt) {
727-
self.trigger('keypress', evt);
728-
729-
if (evt.which === KEYS.SPACE) {
730-
evt.preventDefault();
731-
}
732-
});
733-
734-
container.on('results:focus', function (params) {
735-
self.$selection.attr('aria-activedescendant', params.data._resultId);
736-
});
737-
738737
container.on('selection:update', function (params) {
739738
self.update(params.data);
740739
});
@@ -782,11 +781,14 @@ define('select2/selection/multiple',[
782781

783782
MultipleSelection.prototype.render = function () {
784783
var $selection = $(
785-
'<span class="multiple-select">' +
784+
'<span class="multiple-select" tabindex="0" role="combobox" ' +
785+
'aria-autocomplete="list" aria-haspopup="true" aria-expanded="false">' +
786786
'<ul class="rendered-selection"></ul>' +
787787
'</span>'
788788
);
789789

790+
$selection.attr('title', this.$element.attr('title'));
791+
790792
this.$selection = $selection;
791793

792794
return $selection;

dist/js/select2.full.js

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10105,11 +10105,31 @@ define('select2/selection/base',[
1010510105
BaseSelection.prototype.bind = function (container, $container) {
1010610106
var self = this;
1010710107

10108+
var id = container.id + '-container';
10109+
var resultsId = container.id + '-results';
10110+
10111+
this.$selection.attr('aria-owns', resultsId);
10112+
10113+
this.$selection.on('keydown', function (evt) {
10114+
self.trigger('keypress', evt);
10115+
10116+
if (evt.which === KEYS.SPACE) {
10117+
evt.preventDefault();
10118+
}
10119+
});
10120+
10121+
container.on('results:focus', function (params) {
10122+
self.$selection.attr('aria-activedescendant', params.data._resultId);
10123+
});
10124+
1010810125
container.on('selection:update', function (params) {
1010910126
self.update(params.data);
1011010127
});
1011110128

1011210129
container.on('open', function () {
10130+
// When the dropdown is open, aria-expanded="true"
10131+
self.$selection.attr('aria-expanded', 'true');
10132+
1011310133
$(document.body).on('mousedown.select2.' + container.id, function (e) {
1011410134
var $target = $(e.target);
1011510135

@@ -10129,10 +10149,16 @@ define('select2/selection/base',[
1012910149
$element.select2('close');
1013010150
});
1013110151
});
10152+
});
1013210153

10133-
container.on('close', function () {
10134-
$(document.body).off('mousedown.select2.' + container.id);
10135-
});
10154+
container.on('close', function () {
10155+
// When the dropdown is closed, aria-expanded="false"
10156+
self.$selection.attr('aria-expanded', 'false');
10157+
self.$selection.removeAttr('aria-activedescendant');
10158+
10159+
self.$selection.focus();
10160+
10161+
$(document.body).off('mousedown.select2.' + container.id);
1013610162
});
1013710163
};
1013810164

@@ -10220,11 +10246,9 @@ define('select2/selection/single',[
1022010246
SingleSelection.__super__.bind.apply(this, arguments);
1022110247

1022210248
var id = container.id + '-container';
10223-
var resultsId = container.id + '-results';
1022410249

1022510250
this.$selection.find('.rendered-selection').attr('id', id);
1022610251
this.$selection.attr('aria-labelledby', id);
10227-
this.$selection.attr('aria-owns', resultsId);
1022810252

1022910253
this.$selection.on('mousedown', function (evt) {
1023010254
// Only respond to left clicks
@@ -10237,19 +10261,6 @@ define('select2/selection/single',[
1023710261
});
1023810262
});
1023910263

10240-
container.on('open', function () {
10241-
// When the dropdown is open, aria-expanded="true"
10242-
self.$selection.attr('aria-expanded', 'true');
10243-
});
10244-
10245-
container.on('close', function () {
10246-
// When the dropdown is closed, aria-expanded="false"
10247-
self.$selection.attr('aria-expanded', 'false');
10248-
self.$selection.removeAttr('aria-activedescendant');
10249-
10250-
self.$selection.focus();
10251-
});
10252-
1025310264
this.$selection.on('focus', function (evt) {
1025410265
// User focuses on the container
1025510266
});
@@ -10258,18 +10269,6 @@ define('select2/selection/single',[
1025810269
// User exits the container
1025910270
});
1026010271

10261-
this.$selection.on('keydown', function (evt) {
10262-
self.trigger('keypress', evt);
10263-
10264-
if (evt.which === KEYS.SPACE) {
10265-
evt.preventDefault();
10266-
}
10267-
});
10268-
10269-
container.on('results:focus', function (params) {
10270-
self.$selection.attr('aria-activedescendant', params.data._resultId);
10271-
});
10272-
1027310272
container.on('selection:update', function (params) {
1027410273
self.update(params.data);
1027510274
});
@@ -10317,11 +10316,14 @@ define('select2/selection/multiple',[
1031710316

1031810317
MultipleSelection.prototype.render = function () {
1031910318
var $selection = $(
10320-
'<span class="multiple-select">' +
10319+
'<span class="multiple-select" tabindex="0" role="combobox" ' +
10320+
'aria-autocomplete="list" aria-haspopup="true" aria-expanded="false">' +
1032110321
'<ul class="rendered-selection"></ul>' +
1032210322
'</span>'
1032310323
);
1032410324

10325+
$selection.attr('title', this.$element.attr('title'));
10326+
1032510327
this.$selection = $selection;
1032610328

1032710329
return $selection;

dist/js/select2.full.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)