Skip to content

Commit

Permalink
Merge pull request #23 from uConnect/vcc-2970/label-for
Browse files Browse the repository at this point in the history
VCC-3455 Update the `for` attribute on the label to match the ID on the select/input
  • Loading branch information
stephymiehle committed Apr 9, 2024
2 parents 110f081 + 4024057 commit f5303c7
Show file tree
Hide file tree
Showing 6 changed files with 866 additions and 2 deletions.
2 changes: 1 addition & 1 deletion dist/combobo.js

Large diffs are not rendered by default.

34 changes: 33 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ module.exports = class Combobo {
inputDivEl.setAttribute('tabindex', '0');
inputDivEl.id = `${input.id}-combobo`; // Prevent duplicate IDs with hidden <input>

// Rewrite the label's `for` attribute to match the new combobox <div>'s ID
this.reassignLabel(input, inputDivEl.id);

input = inputDivEl;
}
}
Expand Down Expand Up @@ -203,6 +206,31 @@ module.exports = class Combobo {

}

/**
* Reassign the label when the original combobox markup has been transformed. This will always
* happen for <select> elements, but may also happen for <input> elements if the `selectOnly`
* option is enabled.
*
* If there is a paired <label> element whose `for` matches the `id` of the original
* input element, it will be reassigned to the new combobox element. Otherwise, if a <label> is a
* previous sibling of the original input element, the `for` attribute will be added and
* referenced to the new combobox element.
*
* @param {*} el The <input> or <select> element
* @param {*} id The ID of the newly-created or transformed combobox
*/
reassignLabel(el, id) {
if (el.labels.length) {
const label = el.labels[0];
label.htmlFor = id;
} else {
const prevEl = el.previousElementSibling;
if (prevEl && prevEl.tagName.toLowerCase() === 'label') {
prevEl.htmlFor = id;
}
}
}

initEvents() {
Emitter(this);
if (!this.optionsWithKeyEventHandlers.has(this.input)) {
Expand Down Expand Up @@ -840,7 +868,11 @@ module.exports = class Combobo {
input.className = this.config.inputClass;
input.id = `${selectElement.id}-input`;
comboElement.appendChild(input);


// Rewrite the label's `for` attribute to match the new input's ID (necessary because the
// <select> element gets hidden).
this.reassignLabel(selectElement, input.id);

// Create the toggle button
const toggleButton = document.createElement('span');
toggleButton.setAttribute('aria-hidden', 'true');
Expand Down
Loading

0 comments on commit f5303c7

Please sign in to comment.