add dropdown document
This commit is contained in:
@ -62,6 +62,23 @@ function selectItems(label, itemlist, htmlkey, textkey) {
|
||||
}
|
||||
}
|
||||
|
||||
function filterSource(searchkeys, textkey, key, source) {
|
||||
if (!Array.isArray(searchkeys) || searchkeys.length === 0) {
|
||||
searchkeys = [textkey];
|
||||
}
|
||||
if (key.length > 0) {
|
||||
source = source.filter(it => {
|
||||
for (let k of searchkeys) {
|
||||
if (contains(it[k].toLowerCase(), key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
class Dropdown {
|
||||
#options;
|
||||
|
||||
@ -120,29 +137,16 @@ class Dropdown {
|
||||
|
||||
// label or input
|
||||
let label;
|
||||
let searchkeys = options.searchkeys;
|
||||
if (!Array.isArray(searchkeys) || searchkeys.length === 0) {
|
||||
searchkeys = [options.textkey];
|
||||
}
|
||||
if (options.input) {
|
||||
label = document.createElement('input');
|
||||
label.className = 'dropdown-text';
|
||||
label.setAttribute('type', 'text');
|
||||
options.placeholder && label.setAttribute('placeholder', options.placeholder);
|
||||
isPositive(options.maxlength) && label.setAttribute('maxlength', options.maxlength);
|
||||
isPositive(options.tabindex) && label.setAttribute('tabindex', options.tabindex);
|
||||
label.addEventListener('input', e => {
|
||||
const key = e.target.value.toLowerCase();
|
||||
let source = this.source;
|
||||
if (key.length > 0) {
|
||||
source = source.filter(it => {
|
||||
for (let k of searchkeys) {
|
||||
if (contains(it[k].toLowerCase(), key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
const source = filterSource(options.searchkeys, options.textkey, key, this.source);
|
||||
this.#filllist(source);
|
||||
this.#container.classList.add('active');
|
||||
});
|
||||
@ -217,7 +221,7 @@ class Dropdown {
|
||||
|
||||
get selectedlist() { return this.#selectedList || [] }
|
||||
|
||||
select(selected, init) {
|
||||
select(selected, silence) {
|
||||
if (this.#lastSelected === selected) {
|
||||
return false;
|
||||
}
|
||||
@ -250,12 +254,12 @@ class Dropdown {
|
||||
}
|
||||
}
|
||||
this.#selected = item;
|
||||
if (!init && typeof this.onselected === 'function') {
|
||||
if (!silence && typeof this.onselected === 'function') {
|
||||
this.onselected(item);
|
||||
}
|
||||
}
|
||||
|
||||
selectlist(selectedlist, init) {
|
||||
selectlist(selectedlist, silence) {
|
||||
const source = this.source;
|
||||
const valuekey = this.#options.valuekey;
|
||||
const textkey = this.#options.textkey;
|
||||
@ -276,7 +280,7 @@ class Dropdown {
|
||||
}
|
||||
selectItems(this.#label, itemlist, htmlkey, textkey);
|
||||
this.#selectedList = itemlist;
|
||||
if (!init && typeof this.onselectedlist === 'function') {
|
||||
if (!silence && typeof this.onselectedlist === 'function') {
|
||||
this.onselectedlist(itemlist);
|
||||
}
|
||||
}
|
||||
@ -293,10 +297,6 @@ class Dropdown {
|
||||
panel.className = 'dropdown-panel';
|
||||
// search box
|
||||
if (!options.input && options.search) {
|
||||
let searchkeys = options.searchkeys;
|
||||
if (!Array.isArray(searchkeys) || searchkeys.length === 0) {
|
||||
searchkeys = [textkey];
|
||||
}
|
||||
const search = document.createElement('div');
|
||||
search.className = 'dropdown-search';
|
||||
const input = document.createElement('input');
|
||||
@ -305,17 +305,7 @@ class Dropdown {
|
||||
!nullOrEmpty(options.searchplaceholder) && input.setAttribute('placeholder', options.searchplaceholder);
|
||||
input.addEventListener('input', e => {
|
||||
const key = e.target.value.toLowerCase();
|
||||
let source = this.source;
|
||||
if (key.length > 0) {
|
||||
source = source.filter(it => {
|
||||
for (let k of searchkeys) {
|
||||
if (contains(it[k].toLowerCase(), key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
const source = filterSource(options.searchkeys, options.textkey, key, this.source);
|
||||
this.#filllist(source);
|
||||
})
|
||||
search.appendChild(input);
|
||||
@ -345,32 +335,29 @@ class Dropdown {
|
||||
this.#wrapper.appendChild(panel);
|
||||
}
|
||||
if (flag) {
|
||||
let source = this.source;
|
||||
if (!options.input && options.search) {
|
||||
const search = panel.querySelector('.dropdown-search > input');
|
||||
if (!nullOrEmpty(search?.value)) {
|
||||
source = filterSource(options.searchkeys, options.textkey, search.value, source);
|
||||
}
|
||||
}
|
||||
this.#filllist(source);
|
||||
// slide direction
|
||||
if (!options.slidefixed) {
|
||||
let parent = options.parent ?? document.body;
|
||||
const height = panel.offsetHeight;
|
||||
if (this.#wrapper.offsetTop - parent.offsetTop + DropdownTitleHeight + height >= parent.offsetHeight) {
|
||||
panel.style.marginTop = -height - DropdownTitleHeight - 2;
|
||||
let p = this.#wrapper;
|
||||
let top = p.offsetTop;
|
||||
while ((p = p.parentElement) != null && p !== parent) {
|
||||
top -= p.scrollTop;
|
||||
}
|
||||
if (top - parent.offsetTop + DropdownTitleHeight + panel.offsetHeight >= parent.offsetHeight) {
|
||||
panel.classList.add('slide-up');
|
||||
} else {
|
||||
panel.style.marginTop = null;
|
||||
panel.classList.remove('slide-up');
|
||||
}
|
||||
}
|
||||
panel.classList.add('active');
|
||||
// search input
|
||||
// const inputSearch = panel.querySelector('.dropdown-search > input');
|
||||
// if (!nullOrEmpty(inputSearch.value)) {
|
||||
// const event = new InputEvent('type');
|
||||
// inputSearch.dispatchEvent(event);
|
||||
// }
|
||||
if (!options.input && options.search) {
|
||||
const search = panel.querySelector('.dropdown-search > input');
|
||||
if (!nullOrEmpty(search?.value)) {
|
||||
search.dispatchEvent(new InputEvent('type'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.#filllist(this.source);
|
||||
} else {
|
||||
panel.classList.remove('active');
|
||||
}
|
||||
@ -489,15 +476,13 @@ class Dropdown {
|
||||
dom ??= document.body;
|
||||
const selects = dom.querySelectorAll('select');
|
||||
for (let sel of selects) {
|
||||
let selected;
|
||||
const source = [...sel.children].map(it => {
|
||||
if (it.selected) {
|
||||
selected = it.value;
|
||||
}
|
||||
return { value: it.value, text: it.innerText }
|
||||
});
|
||||
const drop = new Dropdown({
|
||||
selected
|
||||
selected: sel.value,
|
||||
disabled: sel.disabled,
|
||||
tabindex: sel.tabIndex
|
||||
});
|
||||
drop.source = source;
|
||||
sel.parentElement.replaceChild(drop.create(), sel);
|
||||
|
Reference in New Issue
Block a user