1
0
mirror of synced 2025-03-10 06:36:08 +03:00

Clone the tabindex from the original select

Previously Select2 would assume that the tab index for the
`<select>` was `0`, which is the browser default.  Now Select2 will
clone the tab index from the original element, and correctly restore
it when it is destroyed or disabled/enabled.

This closes https://github.com/select2/select2/issues/3031.
This commit is contained in:
Kevin Brown 2015-02-13 23:57:18 -05:00
parent ef5c88a6f6
commit b382fdca9c
10 changed files with 105 additions and 42 deletions

View File

@ -787,12 +787,16 @@ define('select2/selection/base',[
BaseSelection.prototype.render = function () {
var $selection = $(
'<span class="select2-selection" tabindex="0" role="combobox" ' +
'<span class="select2-selection" role="combobox" ' +
'aria-autocomplete="list" aria-haspopup="true" aria-expanded="false">' +
'</span>'
);
this._tabindex = this.$element.data('old-tabindex') ||
this.$element.attr('tabindex') || 0;
$selection.attr('title', this.$element.attr('title'));
$selection.attr('tabindex', this._tabindex);
this.$selection = $selection;
@ -843,7 +847,7 @@ define('select2/selection/base',[
});
container.on('enable', function () {
self.$selection.attr('tabindex', '0');
self.$selection.attr('tabindex', self._tabindex);
});
container.on('disable', function () {
@ -4146,6 +4150,12 @@ define('select2/core',[
Select2.__super__.constructor.call(this);
// Set up the tabindex
var tabindex = $element.attr('tabindex') || 0;
$element.data('old-tabindex', tabindex);
$element.attr('tabindex', '-1');
// Set up containers and adapters
var DataAdapter = this.options.get('dataAdapter');
@ -4203,10 +4213,6 @@ define('select2/core',[
// Synchronize any monitored attributes
this._syncAttributes();
this._tabindex = $element.attr('tabindex') || 0;
$element.attr('tabindex', '-1');
$element.data('select2', this);
};
@ -4595,7 +4601,7 @@ define('select2/core',[
this._sync = null;
this.$element.off('.select2');
this.$element.attr('tabindex', this._tabindex);
this.$element.attr('tabindex', this.$element.data('old-tabindex'));
this.$element.show();
this.$element.removeData('select2');

View File

@ -787,12 +787,16 @@ define('select2/selection/base',[
BaseSelection.prototype.render = function () {
var $selection = $(
'<span class="select2-selection" tabindex="0" role="combobox" ' +
'<span class="select2-selection" role="combobox" ' +
'aria-autocomplete="list" aria-haspopup="true" aria-expanded="false">' +
'</span>'
);
this._tabindex = this.$element.data('old-tabindex') ||
this.$element.attr('tabindex') || 0;
$selection.attr('title', this.$element.attr('title'));
$selection.attr('tabindex', this._tabindex);
this.$selection = $selection;
@ -843,7 +847,7 @@ define('select2/selection/base',[
});
container.on('enable', function () {
self.$selection.attr('tabindex', '0');
self.$selection.attr('tabindex', self._tabindex);
});
container.on('disable', function () {
@ -4146,6 +4150,12 @@ define('select2/core',[
Select2.__super__.constructor.call(this);
// Set up the tabindex
var tabindex = $element.attr('tabindex') || 0;
$element.data('old-tabindex', tabindex);
$element.attr('tabindex', '-1');
// Set up containers and adapters
var DataAdapter = this.options.get('dataAdapter');
@ -4203,10 +4213,6 @@ define('select2/core',[
// Synchronize any monitored attributes
this._syncAttributes();
this._tabindex = $element.attr('tabindex') || 0;
$element.attr('tabindex', '-1');
$element.data('select2', this);
};
@ -4595,7 +4601,7 @@ define('select2/core',[
this._sync = null;
this.$element.off('.select2');
this.$element.attr('tabindex', this._tabindex);
this.$element.attr('tabindex', this.$element.data('old-tabindex'));
this.$element.show();
this.$element.removeData('select2');

View File

@ -1226,12 +1226,16 @@ define('select2/selection/base',[
BaseSelection.prototype.render = function () {
var $selection = $(
'<span class="select2-selection" tabindex="0" role="combobox" ' +
'<span class="select2-selection" role="combobox" ' +
'aria-autocomplete="list" aria-haspopup="true" aria-expanded="false">' +
'</span>'
);
this._tabindex = this.$element.data('old-tabindex') ||
this.$element.attr('tabindex') || 0;
$selection.attr('title', this.$element.attr('title'));
$selection.attr('tabindex', this._tabindex);
this.$selection = $selection;
@ -1282,7 +1286,7 @@ define('select2/selection/base',[
});
container.on('enable', function () {
self.$selection.attr('tabindex', '0');
self.$selection.attr('tabindex', self._tabindex);
});
container.on('disable', function () {
@ -4585,6 +4589,12 @@ define('select2/core',[
Select2.__super__.constructor.call(this);
// Set up the tabindex
var tabindex = $element.attr('tabindex') || 0;
$element.data('old-tabindex', tabindex);
$element.attr('tabindex', '-1');
// Set up containers and adapters
var DataAdapter = this.options.get('dataAdapter');
@ -4642,10 +4652,6 @@ define('select2/core',[
// Synchronize any monitored attributes
this._syncAttributes();
this._tabindex = $element.attr('tabindex') || 0;
$element.attr('tabindex', '-1');
$element.data('select2', this);
};
@ -5034,7 +5040,7 @@ define('select2/core',[
this._sync = null;
this.$element.off('.select2');
this.$element.attr('tabindex', this._tabindex);
this.$element.attr('tabindex', this.$element.data('old-tabindex'));
this.$element.show();
this.$element.removeData('select2');

File diff suppressed because one or more lines are too long

20
dist/js/select2.js vendored
View File

@ -1226,12 +1226,16 @@ define('select2/selection/base',[
BaseSelection.prototype.render = function () {
var $selection = $(
'<span class="select2-selection" tabindex="0" role="combobox" ' +
'<span class="select2-selection" role="combobox" ' +
'aria-autocomplete="list" aria-haspopup="true" aria-expanded="false">' +
'</span>'
);
this._tabindex = this.$element.data('old-tabindex') ||
this.$element.attr('tabindex') || 0;
$selection.attr('title', this.$element.attr('title'));
$selection.attr('tabindex', this._tabindex);
this.$selection = $selection;
@ -1282,7 +1286,7 @@ define('select2/selection/base',[
});
container.on('enable', function () {
self.$selection.attr('tabindex', '0');
self.$selection.attr('tabindex', self._tabindex);
});
container.on('disable', function () {
@ -4585,6 +4589,12 @@ define('select2/core',[
Select2.__super__.constructor.call(this);
// Set up the tabindex
var tabindex = $element.attr('tabindex') || 0;
$element.data('old-tabindex', tabindex);
$element.attr('tabindex', '-1');
// Set up containers and adapters
var DataAdapter = this.options.get('dataAdapter');
@ -4642,10 +4652,6 @@ define('select2/core',[
// Synchronize any monitored attributes
this._syncAttributes();
this._tabindex = $element.attr('tabindex') || 0;
$element.attr('tabindex', '-1');
$element.data('select2', this);
};
@ -5034,7 +5040,7 @@ define('select2/core',[
this._sync = null;
this.$element.off('.select2');
this.$element.attr('tabindex', this._tabindex);
this.$element.attr('tabindex', this.$element.data('old-tabindex'));
this.$element.show();
this.$element.removeData('select2');

File diff suppressed because one or more lines are too long

View File

@ -19,6 +19,12 @@ define([
Select2.__super__.constructor.call(this);
// Set up the tabindex
var tabindex = $element.attr('tabindex') || 0;
$element.data('old-tabindex', tabindex);
$element.attr('tabindex', '-1');
// Set up containers and adapters
var DataAdapter = this.options.get('dataAdapter');
@ -76,10 +82,6 @@ define([
// Synchronize any monitored attributes
this._syncAttributes();
this._tabindex = $element.attr('tabindex') || 0;
$element.attr('tabindex', '-1');
$element.data('select2', this);
};
@ -468,7 +470,7 @@ define([
this._sync = null;
this.$element.off('.select2');
this.$element.attr('tabindex', this._tabindex);
this.$element.attr('tabindex', this.$element.data('old-tabindex'));
this.$element.show();
this.$element.removeData('select2');

View File

@ -14,12 +14,16 @@ define([
BaseSelection.prototype.render = function () {
var $selection = $(
'<span class="select2-selection" tabindex="0" role="combobox" ' +
'<span class="select2-selection" role="combobox" ' +
'aria-autocomplete="list" aria-haspopup="true" aria-expanded="false">' +
'</span>'
);
this._tabindex = this.$element.data('old-tabindex') ||
this.$element.attr('tabindex') || 0;
$selection.attr('title', this.$element.attr('title'));
$selection.attr('tabindex', this._tabindex);
this.$selection = $selection;
@ -70,7 +74,7 @@ define([
});
container.on('enable', function () {
self.$selection.attr('tabindex', '0');
self.$selection.attr('tabindex', self._tabindex);
});
container.on('disable', function () {

View File

@ -123,6 +123,39 @@ test('the container should be in the tab order', function (assert) {
);
});
test('a custom tabindex is copied', function (assert) {
var $select = $('#qunit-fixture .single');
$select.attr('tabindex', '999');
var selection = new BaseSelection($select, options);
var $selection = selection.render();
var container = new MockContainer();
selection.bind(container, $('<span></span>'));
assert.equal(
$selection.attr('tabindex'),
'999',
'The tab index should match the original tab index'
);
container.trigger('disable');
assert.equal(
$selection.attr('tabindex'),
'-1',
'The selection should be dropped out of the tab order when disabled'
);
container.trigger('enable');
assert.equal(
$selection.attr('tabindex'),
'999',
'The tab index should be restored when re-enabled'
);
});
module('Accessibility - Single');
test('aria-labelledby should match the rendered container', function (assert) {

View File

@ -7,19 +7,19 @@
<body>
<div id="qunit"></div>
<div id="qunit-fixture">
<select class="single" title="This is an example title">
<select class="single" title="This is an example title" tabindex="0">
<option value="default">Default</option>
<option value="1">One</option>
<option>2</option>
</select>
<select class="multiple" multiple="multiple" title="One more example title">
<select class="multiple" multiple="multiple" title="One more example title" tabindex="0">
<option value="default">Default</option>
<option value="1">One</option>
<option>2</option>
</select>
<select class="groups">
<select class="groups" tabindex="0">
<optgroup label="Test">
<option value="one">One</option>
<option value="two">Two</option>