Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dropdown options missing IDs #4350

Closed
afercia opened this issue May 10, 2016 · 2 comments · Fixed by #5586
Closed

Dropdown options missing IDs #4350

afercia opened this issue May 10, 2016 · 2 comments · Fixed by #5586

Comments

@afercia
Copy link

afercia commented May 10, 2016

Note: this issue is part of several steps that should be taken to make the Select2 list options accessible, see #3735 and #4349.

Each item in the results list should always have an unique ID to be used as value for aria-activedescendant on the search field (or on the selection element when the search is hidden).

Without aria-activedescendant (and aria-owns and other aria attributes), assistive technologies can't understand which item in the list is currently "highlighted", thus they can't announce its content.

As far as I see, Select2 is based on various "data adapters" to normalize the data to pass to the widget. See BaseAdapter, SelectAdapter, ArrayAdapter, AjaxAdapter, etc. On the other hand, each item object in the results list is "normalized" by a _normalizeItem() function which in turn calls generateResultId()

If I'm not wrong, this is the relevant call in src/js/select2/data/select.js

if (item._resultId == null && item.id && this.container != null) {
  item._resultId = this.generateResultId(this.container, item);
}

It seems this fails for some adapters (e.g. array, ajax, tags) because at this point this.container is null. See in the screenshot below "red", "blue", and "green" don't have an ID:

07 missing ids

I'd appreciate any feedback here. Also, I'm not sure I can find a fix without help from someone with more advanced coding abilities than me :) Wondering what to do here, maybe the simpler thing would be using a different way to generate a unique ID?

@kevin-brown
Copy link
Member

This appears to only happen for items passed in as data, making it an issue in the ArrayAdapter.

@stale
Copy link

stale bot commented Mar 13, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the status: stale label Mar 13, 2019
@stale stale bot closed this as completed Mar 20, 2019
@kevin-brown kevin-brown reopened this Jul 25, 2019
@stale stale bot removed the status: stale label Jul 25, 2019
@kevin-brown kevin-brown added this to the 4.0.9 milestone Jul 25, 2019
kevin-brown added a commit that referenced this issue Jul 25, 2019
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
kevin-brown added a commit that referenced this issue Jul 27, 2019
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
kevin-brown added a commit that referenced this issue Jul 27, 2019
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
@kevin-brown kevin-brown removed this from the 4.0.9 milestone Jul 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants