In order to enable the ability to uniquely identify a result by an ID
in the DOM, we generate a new ID for the result based on a combination
of things, including the container ID prefix that is generated and
used elsewhere in Select2. This has worked fairly well for use cases
including attaching Select2 to an existing `<select>` and loading in
options from a remote data set.
Unfortunately, because this process relied on the container ID being
used as a prefix, this failed for options which were automatically
generated on initialization using the `data:` option to Select2.
These were not being generated with an ID because at the time that
they were being generated, the data adapter was not aware of the
container it was being used in. This broke some accessibility features
because we had a mix of options in the results list with IDs, and
some without, so we fixed the ordering to make this work.
Option generation no longer happens when the data adapter is first
initialized, which is where it was previously happening, and instead
it now occurs when the data adapter is bound to the container. This
allows us to ensure that the data adapter is always aware of the
container it is being associated with, so now it will be able to
generate the result IDs.
This also fixes the tests for the array adapter as well as the
legacy `<input />` adapter so they properly bind to a container
during the test. This was causing test failures becuase the options
which would previously be generated during initialization were no
longer appearing.
Fixes#4350
* Rewrote maximumSelectionLength tests to use container
These brings the tests in line with other tests which we have, and
makes it easier to understand what is actually going on in the tests.
This also removes a redundant set of tests where we were testing with
=> 2 options being allowed. There are no current edge cases that would
have required this.
* Fix maximumSelectionLength being ignored by closeOnSelect
There was a bug where the `maximumSelectionLength` option would not
kick in if the `closeOnSelect` option was enabled. Normally, this
was enabled by someone in their global configuration, but it could
also be seen when somoene selected an option while holding the
meta/ctrl/alt keys. This would implicitly enable the `closeOnSelect`
behaviour, even when it was not globally enabled, and cause the bug.
This fixes that issue by listening to the `select` event which is
triggered whenever an option is selected, and triggers the "maximum
selected" message based on that event. This should now force the
message to be displayed, even when the results did not have to be
queried another time.
Fixes#3514Fixes#3860Closes#5333
* Update tests to be compatible with jQuery 3.0.0
There was a change in jQuery 3 that ensures that the return value of `.val()` on a multiple select is always an array. This is a breaking change from previous versions, where `null` or `undefined` were returned in these scenarios. Because we cannot `assert.equal` on a list of possible values, these assertions were switched to `assert.ok` which should be good enough.
* Properly strip out units in positioning tests
Before we were assuming that there were no units, and only were we stripping them out if we were expecting 3 digits. Now we just strip out all non-digit characters, so that should do the job and get us what we want.
There was a change in jQuery 3.2.0 that caused the units to be returned in these specific calls. They were not previously being returned, so this was not actually an issue.
* Add automated testing against jQuery 3.4.1
No tests appear to be currently failing.
After we upgraded to QUnit 1.23.1, we gained support for
assert.expect(). This allows us to guard against any race conditions
within tests, because now expect() will be linked to the specific test
instead of the current running test.
This adds a broken test that demonstrates the issue seen in
https://github.com/select2/select2/issues/3990 where existing selected
options are being reset once Select2 is initialized. This issue cannot
be reproduced on the options page [1] because the issue only appear to
happen if the selected option is not the first one in the list of
possible options.
[1]: https://select2.github.io/examples.html#data-array
This strips whitespace in tags by default, so multiple tags cannot
be created with only whitespace as the difference in the id.
A test has been added to ensure that this remains fixed in the future.
This closes https://github.com/select2/select2/issues/3076.
This fixes an issue when using a `<select>` where the elements were
created with XHTML-encoded characters to prevent any injection, as
they would be double-encoded and display incorrectly.
When using a `<select>`, we can assume that the data has already
been encoded because any XSS will have already run before we get to
it. Because of this, we can just use `.text()` instead of `.html()`
to avoid any issues.
This also includes a test to ensure that this does not become an
issue in the future.
This closes https://github.com/select2/select2/issues/3115.
This groups tests into common HTML files so they can be run more
quickly. This also reduces the number of Sauce Labs instances that
have to be run, as one instance was previously spun up for each
file.
This adds a check that triggers an error if Select2 was not able
to detect a copy of jQuery on the page. This should help users when
they are setting up Select2.
**Breaking change:** The full build no longer includes jQuery.
Previously, the full build included all requirements for Select2,
including jQuery, which meant that anyone looking for the optional
requirements had to possibly include multiple versions of jQuery
on their page. This means that anyone requiring Select2 to also
bundle jQuery will now need to include jQuery on their pages
alongside Select2. A copy of jQuery is included in the repository.
**Breaking change:** The AMD build of Select2 will now correctly
wrap the code in a `define` block. It will still create the named
blocks inside of the code, which should be valid in most AMD build
systems, so now Select2 is compatible with cases where the file
does not have the same name as the Select2 module name.
**Breaking change:** Select2 will re-use the AMD methods if they
are available on the page, but it will not longer leak the included
AMD loader to the global scope. The AMD methods will still be
available on the `jQuery.fn.select2.amd` namespace.
The `mock.js` test file has been renamed to `helpers.js` and will
handle the escalation of the `require` and `define` variables to
the global scope. It should be included in all test files, or the
tests will fail.
This closes https://github.com/select2/select2/issues/2946.
This adds a test that makes sure that the inline data attribute
overrides the options that are passed in during initialization.
This also adds a test for the `createTag` option, which is used
when tagging.
While deep nesting will not work on a standard `<select>`, we can
emulate it through data objects still, and just handle the display
of the data in the results.
This also means that the horrific deep-nested CSS is back to handle
the padding. I hope that will get fixed over time.
This also fixes one of the performance issues with adding array
data, as options are added at the very end instead of one by one.
There was a plan to universally use an array as the return from
query methods, but now that we've realized pagination and extra
things are impossible without it, we're going back to the return
object. Anyone looking to migrate their data should be returning
an object with the key `results` containing what they previously
returned.
This should fix https://github.com/select2/select2/issues/2898
Now that the data objects have the `element` property, we can test
to make sure it's a DOM element and then use it for selecting the
option. This allows us to select multiple options with the same id,
as well as handle cases where that is already happening.
You cannot use `$e.val()` to select two options with the same id,
as jQuery will reject it, but you can set the second option to
`.selected = true`, which is supported.
This improves the speeds of creating the `<option>` tags for array
data. By creating the HTML ahead of time and putting it into an
`<option>` element before passing it to jQuery, it cuts down on the
time it takes for jQuery to process the HTML string and convert it
into DOM elements. This proved to be incredibly slow.
This also changes the `item` function to return early when the
data exists. The `$e.data` call has also been switched to a
`$.data` call, which doesn't need to check the DOM to see if the
data attributes already exist. This cuts down on a bit of wasted
time, as the `data` key should never be present in the DOM, and it
should be ignored if it is.
This converts individual objects passed in through the `array`
parameter to `<option>` tags when Select2 is initialized. This
removes a lot of duplicate code from the `ArrayAdapter`, and keeps
everything closer to the native `<select>` element.
This introduces a breaking change from previous versions of Select2,
where the initial value for array data was blank, even if a blank
option was not present in the original array of objects. Now the
first object passed in will be selected by default, following the
behavior of a standard `<select>` element.
This breaking change does not affect `<select multiple="multiple">`
elements, which by default have no selection.
When using array data, and an option is selected, the data that is
attached to the DOM element will be run through `item` and should
have any private, automatically generated attributes added and
merged with it.
We should only be checking the option values that matter, such as
`id` and `text`, instead of checking all of the option values. This
will prevent unexpected breaking when new properties are added to
the options.
Existing properties should be covered by tests to avoid regressions.
We have to enforce ids being strings as the values of options within
a select will always be an id. This fixes an issue that we had with
array selections not being highlighted in the results.