JSFiddle - React, Tailwind, and code Playground
by dumptyd
HTML
<div id="target"></div>
SCSS
.kb-select {
border: 1px solid #888;
padding: 5px;
display: inline-block;
.kb-select-popup-wrapper:not(.visible) {
display: none;
}
.kb-select-popup-wrapper {
.kb-select-search {
border: 1px solid #ccc;
padding: 5px;
}
}
}
JavaScript
const $$ = document.querySelectorAll.bind(document);
const $ = document.querySelector.bind(document);
const el = $('#target');
const data = ['Apple', 'Banana', 'Cat', 'Bank', 'Elephant', 'Frog', 'Giraffe'];
class KbSelect {
constructor(el, data, options={}) {
if (!el || !data || !data.length) {
throw new Error('Invalid parameters.');
}
this.el = el;
this.itemClass = options.itemClass || 'kb-select-item';
this.searchClass = options.searchClass || 'kb-select-search';
this.elements = this._generateItems(data);
this.filteredElements = this.elements.slice();
this._createUI();
}
_generateItems(data) {
return data.map(d => this._createItem(d));
}
_createItem(label) {
const div = document.createElement('DIV');
div.classList.add(this.itemClass);
div.innerText = label;
return div;
}
_createSearch() {
const input = document.createElement('INPUT');
input.classList.add(this.searchClass);
const valMap = { type: 'text', placeholder: 'Search' };
Object.keys(valMap).forEach(k => {
input[k] = valMap[k];
});
input.addEventListener('input', this._changeHandler.bind(this));
return input;
}
_changeHandler(e) {
const val = e.target.value.toLowerCase();
this.filteredElements = this.elements.filter(e => e.innerText.toLowerCase().includes(val));
this._triggerOptionsChange();
}
_createUI() {
const popupWrapper = document.createElement('DIV');
popupWrapper.classList.add('kb-select-popup-wrapper');
this.popupWrapper = popupWrapper;
const itemWrapper = document.createElement('DIV');
itemWrapper.classList.add('kb-select-item-wrapper');
this.itemWrapper = itemWrapper;
const valEl = document.createElement('DIV');
valEl.classList.add('kb-select-display');
valEl.innerText = 'Select a value';
valEl.addEventListener('click', () => {
this.popupWrapper.classList.toggle('visible');
});
this.el.classList.add('kb-select');
...