build-selectbox
Learn to build a single component in plain html, css, js - a select box by following a tutorial by Web Dev Simplified.
You can find the Web dev Simplified [Github Starter Kit](https://github.com/WebDevSimplified/custom-select-dropdown) here.
Lessons learned
This approach uses the build in state management of the input select field to store informations. Its actually hidden inside the code. If the Javascript is deactivated, there is still a selectbox available.
The functionality is build with an object and a lot of eventListener.
The Styling is very basic, but it can be everything you like.
Translation
Because i found the naming a little destracting here my personal list
js-property | html-tag | representation |
---|---|---|
customElement | div | the custom selectfield mockup |
labelElement | span | the label/ name inside the custom selectfield |
optionsCustomElement | ul | the list itself |
optionElement | li | option-tag inside the select-field |
Lessons
RECAP: debouncing for searching input (500ms)
let debounceTimeout;
let searchTerm = '';
...
clearTimeout(debounceTimeout);
searchTerm += event.key;
debounceTimeout = setTimeout(() => {
searchTerm = '';
}, 500);
RECAP: handling key strokes
select.customElement.addEventListener('keydown', (event) => {
switch (event.code) {
case 'Space':
...
break;
case 'ArrowUp':
...
break;
case 'ArrowDown':
...
break;
case 'Enter':
case 'Escape':
...
}
getting the informations stored in option state
export default class Select {
constructor(element) {
...
this.options = getFormattedOptions(element.querySelectorAll('option'));
...
}
}
...
function getFormattedOptions(optionElements) {
return [...optionElements].map((optionElement) => {
return {
value: optionElement.value,
label: optionElement.label,
selected: optionElement.selected,
element: optionElement,
};
});
}
creating the list inside the custom made select field
select.options.forEach((option) => {
const optionElement = document.createElement('li');
optionElement.classList.add('custom-select-option');
optionElement.classList.toggle('selected', option.selected);
optionElement.innerText = option.label;
optionElement.dataset.value = option.value;
optionElement.addEventListener('click', () => {
select.selectValue(option.value);
select.optionsCustomElement.classList.remove('show');
});
select.optionsCustomElement.append(optionElement);
});
giving a div a focus
select.customElement.tabIndex = 0;
scroll to a specific item
.custom-select-options {
...
max-height: 200px;
overflow: scroll;
}
...
newCustomElement.scrollIntoView({ block: 'nearest' });
...
react on loosing focus on an element
select.customElement.addEventListener('blur', () => {
select.optionsCustomElement.classList.remove('show');
});