Skip to content

Commit

Permalink
Support the autocomplete attribute being set on the original <select> (
Browse files Browse the repository at this point in the history
…select2#5839)

* Add test to ensure search autocomplete attribute is set

This adds a basic test to make sure that the `autocomplete` attribute
on the search box is set based on the value of the `autocomplete`
option that is passed in to Select2. This alows people to set the
`autocomplete` attribute on their `<select>`, which is valid
according to the spec, and have it copy over to the search box of
their Select2 instance.

* Add tests for options set by HTML atttributes

This adds some missing tests for the disabled and multiple attributes
and how they can be used to set the corresponding options within
Select2. This also adds tests for the new autocomplete option that
ensures it is properly synchronized based on the attribute being
set.

* Add support for the autocomplete attribute

This will now copy the `autocomplete` attribute (based on the current
state of the `autocomplete` DOM property) from the `<select>` to
any search boxes that are used by Select2. This is necessary to
both handle cases where people do not want the autocomplete
disabled, as well as handling cases where people are looking to set
a custom autocomplete which will assist users when searching.

This still maintains backwards compatibility with the `autocomplete`
option being set to `off` by default. It also allows the
`autocomplete` option to be set through the standard Select2 options
to override the `autocomplete` attribute if it is present.

This does not follow the precedent set by the `disabled` and `multiple`
options where the value is synchronized back to the original
`<select>` when it is overridden by the options. This is because it
would break backwards compatibility because the default state of
the `autocomplete` property is a blank string ('') instead of `off`
which is what Select2 uses.

* Skip autocomplete attr test when not supported

Not all browsers, including older version of PhantomJS, support
the `autocomplete` attribute when it is set on a `<select>` element.
  • Loading branch information
kevin-brown authored Apr 25, 2020
1 parent f30702d commit e41cb2e
Show file tree
Hide file tree
Showing 10 changed files with 223 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/js/select2/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ define([

this.defaults = {
amdLanguageBase: './i18n/',
autocomplete: 'off',
closeOnSelect: true,
debug: false,
dropdownAutoWidth: false,
Expand Down
4 changes: 3 additions & 1 deletion src/js/select2/dropdown/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ define([
var $search = $(
'<span class="select2-search select2-search--dropdown">' +
'<input class="select2-search__field" type="search" tabindex="-1"' +
' autocomplete="off" autocorrect="off" autocapitalize="none"' +
' autocorrect="off" autocapitalize="none"' +
' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
'</span>'
);

this.$searchContainer = $search;
this.$search = $search.find('input');

this.$search.prop('autocomplete', this.options.get('autocomplete'));

$rendered.prepend($search);

return $rendered;
Expand Down
4 changes: 4 additions & 0 deletions src/js/select2/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ define([
this.options.disabled = $e.prop('disabled');
}

if (this.options.autocomplete == null && $e.prop('autocomplete')) {
this.options.autocomplete = $e.prop('autocomplete');
}

if (this.options.dir == null) {
if ($e.prop('dir')) {
this.options.dir = $e.prop('dir');
Expand Down
4 changes: 3 additions & 1 deletion src/js/select2/selection/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ define([
var $search = $(
'<li class="select2-search select2-search--inline">' +
'<input class="select2-search__field" type="search" tabindex="-1"' +
' autocomplete="off" autocorrect="off" autocapitalize="none"' +
' autocorrect="off" autocapitalize="none"' +
' spellcheck="false" role="searchbox" aria-autocomplete="list" />' +
'</li>'
);

this.$searchContainer = $search;
this.$search = $search.find('input');

this.$search.prop('autocomplete', this.options.get('autocomplete'));

var $rendered = decorated.call(this);

this._transferTabIndex();
Expand Down
49 changes: 49 additions & 0 deletions tests/dropdown/search-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
module('Dropdown - Search');

var Dropdown = require('select2/dropdown');
var DropdownSearch = Utils.Decorate(
Dropdown,
require('select2/dropdown/search')
);

var $ = require('jquery');
var Options = require('select2/options');
var Utils = require('select2/utils');

var options = new Options({});

test('search box defaults autocomplete to off', function (assert) {
var $select = $('#qunit-fixture .single');

var dropdown = new DropdownSearch($select, options);
var $dropdown = dropdown.render();

var container = new MockContainer();
dropdown.bind(container, $('<span></span>'));

assert.equal(
$dropdown.find('input').attr('autocomplete'),
'off',
'The search box has autocomplete disabled'
);
});

test('search box sets autocomplete from options', function (assert) {
var $select = $('#qunit-fixture .single');

var autocompleteOptions = new Options({
autocomplete: 'country-name'
});

var dropdown = new DropdownSearch($select, autocompleteOptions);
var $dropdown = dropdown.render();

var container = new MockContainer();
dropdown.bind(container, $('<span></span>'));

assert.equal(
$dropdown.find('input').attr('autocomplete'),
'country-name',
'The search box sets the right autocomplete attribute'
);
});
113 changes: 113 additions & 0 deletions tests/options/element-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
module('Options - Copying from element');

var $ = require('jquery');

var Options = require('select2/options');

test('copies disabled attribute when set', function (assert) {
var $test = $('<select disabled></select>');

var options = new Options({}, $test);

assert.ok(options.get('disabled'));
});

test('does not copy disabled attribute when not set', function (assert) {
var $test = $('<select></select>');

var options = new Options({}, $test);

assert.ok(!options.get('disabled'));
});

test('disabled attribute does not override disable option', function (assert) {
var $test = $('<select disabled></select>');

var options = new Options({
disabled: false
}, $test);

assert.ok(!options.get('disabled'));
});

test('disabled option is synchronized back', function (assert) {
var $test = $('<select disabled></select>');

assert.ok($test.prop('disabled'));

var options = new Options({
disabled: false
}, $test);

assert.ok(!$test.prop('disabled'));
});

test('copies multiple attribute when set', function (assert) {
var $test = $('<select multiple></select>');

var options = new Options({}, $test);

assert.ok(options.get('multiple'));
});

test('does not copy multiple attribute when not set', function (assert) {
var $test = $('<select></select>');

var options = new Options({}, $test);

assert.ok(!options.get('multiple'));
});

test('multiple attribute does not override multiple option', function (assert) {
var $test = $('<select multiple></select>');

var options = new Options({
multiple: false
}, $test);

assert.ok(!options.get('multiple'));
});

test('multiple option is synchronized back', function (assert) {
var $test = $('<select multiple></select>');

assert.ok($test.prop('multiple'));

var options = new Options({
multiple: false
}, $test);

assert.ok(!$test.prop('multiple'));
});

test('copies autocomplete attribute when set', function (assert) {
var $test = $('<select autocomplete="country-name"></select>');

if ($test.prop('autocomplete') !== 'country-name') {
// Browser does not support the autocomplete attribute on a select
assert.ok(true);
return;
}

var options = new Options({}, $test);

assert.equal(options.get('autocomplete'), 'country-name');
});

test('does not copy autocomplete attribute when not set', function (assert) {
var $test = $('<select></select>');

var options = new Options({}, $test);

assert.equal(options.get('autocomplete'), 'off');
});

test('autocomplete attribute does not override option', function (assert) {
var $test = $('<select autocomplete="country-name"></select>');

var options = new Options({
autocomplete: 'organization'
}, $test);

assert.ok(options.get('autocomplete'), 'organization');
});
44 changes: 44 additions & 0 deletions tests/selection/search-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,3 +275,47 @@ test('search box with text should not close dropdown', function (assert) {
$search.val('test');
$search.trigger('click');
});

test('search box defaults autocomplete to off', function (assert) {
var $select = $('#qunit-fixture .multiple');

var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch);
var selection = new CustomSelection($select, options);
var $selection = selection.render();

var container = new MockContainer();
selection.bind(container, $('<span></span>'));

// Update the selection so the search is rendered
selection.update([]);

assert.equal(
$selection.find('input').attr('autocomplete'),
'off',
'The search box has autocomplete disabled'
);
});

test('search box sets autocomplete from options', function (assert) {
var $select = $('#qunit-fixture .multiple');

var autocompleteOptions = new Options({
autocomplete: 'country-name'
});

var CustomSelection = Utils.Decorate(MultipleSelection, InlineSearch);
var selection = new CustomSelection($select, autocompleteOptions);
var $selection = selection.render();

var container = new MockContainer();
selection.bind(container, $('<span></span>'));

// Update the selection so the search is rendered
selection.update([]);

assert.equal(
$selection.find('input').attr('autocomplete'),
'country-name',
'The search box sets the right autocomplete attribute'
);
});
2 changes: 2 additions & 0 deletions tests/unit-jq1.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,14 @@
<script src="dropdown/dropdownCss-tests.js" type="text/javascript"></script>
<script src="dropdown/dropdownParent-tests.js" type="text/javascript"></script>
<script src="dropdown/positioning-tests.js" type="text/javascript"></script>
<script src="dropdown/search-tests.js" type="text/javascript"></script>
<script src="dropdown/search-a11y-tests.js" type="text/javascript"></script>
<script src="dropdown/selectOnClose-tests.js" type="text/javascript"></script>
<script src="dropdown/stopPropagation-tests.js" type="text/javascript"></script>

<script src="options/ajax-tests.js" type="text/javascript"></script>
<script src="options/data-tests.js" type="text/javascript"></script>
<script src="options/element-tests.js" type="text/javascript"></script>
<script src="options/translation-tests.js" type="text/javascript"></script>
<script src="options/width-tests.js" type="text/javascript"></script>

Expand Down
2 changes: 2 additions & 0 deletions tests/unit-jq2.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,14 @@
<script src="dropdown/dropdownCss-tests.js" type="text/javascript"></script>
<script src="dropdown/dropdownParent-tests.js" type="text/javascript"></script>
<script src="dropdown/positioning-tests.js" type="text/javascript"></script>
<script src="dropdown/search-tests.js" type="text/javascript"></script>
<script src="dropdown/search-a11y-tests.js" type="text/javascript"></script>
<script src="dropdown/selectOnClose-tests.js" type="text/javascript"></script>
<script src="dropdown/stopPropagation-tests.js" type="text/javascript"></script>

<script src="options/ajax-tests.js" type="text/javascript"></script>
<script src="options/data-tests.js" type="text/javascript"></script>
<script src="options/element-tests.js" type="text/javascript"></script>
<script src="options/translation-tests.js" type="text/javascript"></script>
<script src="options/width-tests.js" type="text/javascript"></script>

Expand Down
2 changes: 2 additions & 0 deletions tests/unit-jq3.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,14 @@
<script src="dropdown/dropdownCss-tests.js" type="text/javascript"></script>
<script src="dropdown/dropdownParent-tests.js" type="text/javascript"></script>
<script src="dropdown/positioning-tests.js" type="text/javascript"></script>
<script src="dropdown/search-tests.js" type="text/javascript"></script>
<script src="dropdown/search-a11y-tests.js" type="text/javascript"></script>
<script src="dropdown/selectOnClose-tests.js" type="text/javascript"></script>
<script src="dropdown/stopPropagation-tests.js" type="text/javascript"></script>

<script src="options/ajax-tests.js" type="text/javascript"></script>
<script src="options/data-tests.js" type="text/javascript"></script>
<script src="options/element-tests.js" type="text/javascript"></script>
<script src="options/translation-tests.js" type="text/javascript"></script>
<script src="options/width-tests.js" type="text/javascript"></script>

Expand Down

0 comments on commit e41cb2e

Please sign in to comment.