547 lines
20 KiB
JavaScript
547 lines
20 KiB
JavaScript
import ADropdown from '/js/libs/js-ADropdown.js'
|
|
|
|
class ASelectEle extends window.AObject {
|
|
constructor(e, id, p) {
|
|
super();
|
|
this.dropdown = new ADropdown();
|
|
this.parent = p;
|
|
this.id = id;
|
|
this.isFocus = false;
|
|
this.isTextSearch = false;
|
|
this.isSearch = false;
|
|
this.isMultiSelect = false;
|
|
this.multiSelectedItem = [];
|
|
this.element = e;
|
|
this.selectedByIndex = -1;
|
|
this.selectedEleItem = null;
|
|
this.cSubH = null;
|
|
this.changeSearch = false;
|
|
this.changeIndex = false;
|
|
this.isOpen = false;
|
|
this.o = {
|
|
damping: 0.25,
|
|
thumbMinSize: 5,
|
|
renderByPixel: true,
|
|
alwaysShowTracks: true,
|
|
continuousScrolling: true
|
|
};
|
|
this.createElement(e);
|
|
this.updateItem(true);
|
|
}
|
|
lockElement(str = "Loading....") {
|
|
this.dropdown.isLock = true;
|
|
if (this.isMultiSelect) {
|
|
var t = this.cSelectedItem.querySelectorAll(".item:not(input.item)");
|
|
if (t && t.length > 0) t.removeAll();
|
|
} else {
|
|
var t = this.cSelectedItem.querySelectorAll("span");
|
|
if (t && t.length > 0) t.removeAll();
|
|
}
|
|
this.createSelectedText(str);
|
|
this.aSelect.classList.add("lock");
|
|
}
|
|
isLockElement() {
|
|
return this.dropdown.isLock;
|
|
}
|
|
unlockElement() {
|
|
this.dropdown.isLock = false;
|
|
var t = this.cSelectedItem.querySelector("span.text");
|
|
if (t) t.remove();
|
|
this.aSelect.classList.remove("lock");
|
|
}
|
|
updateItem(f = false) {
|
|
if (this.isMultiSelect) {
|
|
this.isMultiSelect = [];
|
|
}
|
|
this.listGroups = [];
|
|
this.listItems = [];
|
|
if (!f) this.resetItem();
|
|
var listOptions = this.element.querySelectorAll("option");
|
|
if (listOptions != null) {
|
|
listOptions.forEach(u => {
|
|
this.addItem(u.getAttribute("value"), u.innerHTML);
|
|
});
|
|
this.update();
|
|
}
|
|
}
|
|
addGroup(id, text) {
|
|
var t = this.groupUI(text);
|
|
this.listGroups.push({ "id": id, "text": text, "subItems": [], "element": t });
|
|
this.updateHeight();
|
|
}
|
|
addItem(id, val) {
|
|
var it = document.createElement("span");
|
|
it.classList.add("ellipsis");
|
|
it.innerHTML = val;
|
|
this.addCustomItem(id, it, val);
|
|
}
|
|
addCustomItem(id, o, vSearch = "", g = null) {
|
|
if (g != null) {
|
|
for (var i = 0; i < this.listGroups.length; i++) {
|
|
if (this.listGroups[i].id = g.id) {
|
|
var lastE = this.listOptions[i].subitems.element;
|
|
var t = this.itemSubUI(id, o, lastE);
|
|
t.setAttribute("index", this.listItems.length);
|
|
this.listItems.push({ "id": id, "o": o, "vSearch": vSearch, "gParent": this.listGroups[i], "element": t });
|
|
this.listGroups[i].subItems.push(this.listItems[this.listItems.length - 1]);
|
|
break;
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
} else {
|
|
var t = this.itemUI(id, o);
|
|
t.setAttribute("index", this.listItems.length);
|
|
this.listItems.push({ "id": id, "o": o, "vSearch": vSearch, "gParent": null, "element": t });
|
|
}
|
|
}
|
|
update() {
|
|
if (!this.isMultiSelect) {
|
|
if (this.listItems.length == 0 && !this.dropdown.isLock) {
|
|
this.createSelectedText("Please choose one of the below options");
|
|
} else {
|
|
this.updateIndex(0);
|
|
}
|
|
}
|
|
this.updateHeight();
|
|
}
|
|
setElement(el, str = "active") {
|
|
if (this.selectedEleItem != null && !this.isMultiSelect) {
|
|
this.selectedEleItem.classList.remove(str);
|
|
}
|
|
el.classList.add(str);
|
|
this.selectedEleItem = el;
|
|
}
|
|
setSelectedItem(value, f = true) {
|
|
if (f) {
|
|
for (var i = 0; i < this.listItems.length; i++) {
|
|
if (this.listItems[i].id == value) {
|
|
this.updateIndex(i);
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
this.updateIndex(value);
|
|
}
|
|
}
|
|
getSelectedItem() {
|
|
return this.selectedItem;
|
|
}
|
|
|
|
updateHeight() {
|
|
var tmp = (this.cSearch ? this.cSearch.clientHeight : 0);
|
|
var tmp1 = this.maxHeight - tmp;
|
|
if (this.scrollSub.clientHeight >= tmp1 && this.cSubH == null) {
|
|
this.cSubH = (this.maxHeight - tmp - 8);
|
|
this.cSub.style.minHeight = this.cSubH + "px";
|
|
if (this.isOpen) {
|
|
this.cSub.parentNode.style.height = this.maxHeight + "px";
|
|
}
|
|
return;
|
|
}
|
|
if (this.scrollSub.clientHeight < tmp1) {
|
|
this.cSubH = null;
|
|
this.cSub.style.minHeight = this.scrollSub.clientHeight + "px";
|
|
if (this.isOpen) {
|
|
this.cSub.parentNode.style.height = (this.scrollSub.clientHeight + tmp) + "px";
|
|
}
|
|
}
|
|
}
|
|
isItemEqual(it1, it2) {
|
|
return it1.getAttribute("data-value") === it2.getAttribute("data-value");
|
|
}
|
|
updateIndex(idx, f = false) {
|
|
if (this.isOpen) {
|
|
this.changeIndex = true;
|
|
}
|
|
if (this.isMultiSelect) {
|
|
if (this.selectedEleItem != null) this.selectedEleItem.classList.remove("hover");
|
|
|
|
this.selectedEleItem = this.listItems[idx].element;
|
|
this.selectedItem = this.listItems[idx];
|
|
if (f) {
|
|
if (!this.multiSelectedItem.hasItem(this.selectedEleItem, this.isItemEqual)) {
|
|
const item = document.createElement("div");
|
|
item.classList.add("item", "d-f", "a-i-center");
|
|
item.setAttribute("data-id", idx);
|
|
this.cSelectedItem.insertBefore(item, this.cSelectedItem.children[0]);
|
|
this.cloneNodes(this.selectedEleItem, item);
|
|
item.insertAdjacentHTML("beforeend", `<button class="ml-1 noopen action d-f a-i-center j-c-center"><span class="atg atg-x"></span></button>`);
|
|
var bt = item.querySelector("button");
|
|
bt.addEventListener("click", (e => {
|
|
this.removeItem(e.currentTarget.parentNode);
|
|
}).bind(this));
|
|
this.setElement(this.selectedEleItem);
|
|
this.multiSelectedItem.push(this.selectedEleItem);
|
|
}
|
|
this.eleSearch.value = "";
|
|
this.eleSearch.focus();
|
|
}
|
|
this.setElement(this.selectedEleItem, "hover");
|
|
} else {
|
|
this.selectedByIndex = idx;
|
|
if (this.selectedEleItem != null) this.selectedEleItem.classList.remove("active");
|
|
this.selectedEleItem = this.listItems[idx].element;
|
|
this.selectedItem = this.listItems[idx];
|
|
this.removeAllChildNodes(this.cSelectedItem);
|
|
this.cloneNodes(this.selectedEleItem, this.cSelectedItem);
|
|
this.setElement(this.selectedEleItem);
|
|
this.scroll.update();
|
|
this.scroll.scrollIntoView(this.selectedEleItem, {
|
|
offsetTop: this.selectedEleItem.clientHeight
|
|
});
|
|
}
|
|
}
|
|
itemSubUI(id, o, lastE) {
|
|
var t = this.itemBaseUI(id, o);
|
|
lastE.parentNode.insertBefore(t, lastE.nextSibling);
|
|
return t;
|
|
}
|
|
itemUI(id, o) {
|
|
var t = this.itemBaseUI(id, o);
|
|
this.scrollSub.appendChild(t);
|
|
return t;
|
|
}
|
|
itemBaseUI(id, o) {
|
|
var d = document.createElement("div");
|
|
d.classList.add("a-option", "nonhide");
|
|
d.setAttribute("data-value", id);
|
|
d.appendChild(o);
|
|
return d;
|
|
}
|
|
groupUI(text) {
|
|
var d = document.createElement("div");
|
|
d.classList.add("a-option-group", "nonhide");
|
|
d.innerHTML = text;
|
|
return d;
|
|
}
|
|
createSelectedUI() {
|
|
var s = document.createElement("div");
|
|
s.classList.add("d-f", "a-i-center");
|
|
if (this.isMultiSelect) {
|
|
s.classList.add("f-wrap");
|
|
s.setAttribute("item-multiple", "");
|
|
} ;
|
|
this.cSelectedItem = s;
|
|
return s;
|
|
}
|
|
createSelectedText(text) {
|
|
var te = document.createElement("span");
|
|
te.classList.add("ellipsis", "text");
|
|
te.innerHTML = text;
|
|
this.cSelectedItem.insertBefore(te, this.cSelectedItem.children[0]);
|
|
}
|
|
createSubItemUI() {
|
|
var s = document.createElement("div");
|
|
s.classList.add("sub-item", "a-s-sub", "d-f", "f-c");
|
|
var cs = null, inp = null, sH = 0;
|
|
|
|
|
|
if (this.isSearch || this.isMultiSelect) {
|
|
|
|
if (this.isMultiSelect) {
|
|
const t = `<input class="item nonhide" type="input"/>`;
|
|
this.cSelectedItem.insertAdjacentHTML("beforeend", t)
|
|
inp = this.cSelectedItem.querySelector("input.item");
|
|
} else {
|
|
cs = document.createElement("div");
|
|
cs.classList.add("a-search", "nonhide");
|
|
s.appendChild(cs);
|
|
inp = document.createElement("input");
|
|
cs.appendChild(inp);
|
|
s.appendChild(cs);
|
|
this.cSearch = cs;
|
|
}
|
|
this.eleSearch = inp;
|
|
var fv = function (e) {
|
|
if (this.dropdown.isLock) {
|
|
return;
|
|
}
|
|
if (!this.isFocus) {
|
|
window.fireEvent(this.aSelect, "click");
|
|
this.isFocus = true;
|
|
}
|
|
this.inputSearchEvent.call(this, e);
|
|
|
|
}.bind(this);
|
|
inp.addEventListener("keyup", fv, false);
|
|
var fv1 = function (e) {
|
|
this.keyDown.call(this, e);
|
|
}.bind(this);
|
|
inp.addEventListener("keydown", fv1, false);
|
|
|
|
}
|
|
var sub = document.createElement("div");
|
|
sub.classList.add("w-100");
|
|
sub.setAttribute("style", "height:auto");
|
|
this.cSub = sub;
|
|
var s1 = document.createElement("div");
|
|
s1.classList.add("d-f", "f-c", "sub-items");
|
|
sub.appendChild(s1);
|
|
this.scrollSub = s1;
|
|
s.appendChild(sub);
|
|
return s;
|
|
}
|
|
createElement(e) {
|
|
var d = document.createElement("div");
|
|
d.classList.add("con-aselect");
|
|
if (e.getAttribute("data-container-width") != null) {
|
|
d.style.width = e.getAttribute("data-container-width");
|
|
}
|
|
d.setAttribute("data-dropdown", "");
|
|
var cselect = document.createElement("div");
|
|
cselect.classList.add("hide");
|
|
d.appendChild(cselect);
|
|
var f = document.createElement("div");
|
|
for (var i = 0; i < e.classList.length; i++) {
|
|
f.classList.add(e.classList[i]);
|
|
}
|
|
var atts = e.attributes;
|
|
for (var i = 0; i < atts.length; i++) {
|
|
if (atts[i].nodeName == "id" || atts[i].nodeName == "name") {
|
|
continue;
|
|
}
|
|
if (atts[i].nodeName == "data-max-height") {
|
|
this.maxHeight = atts[i].nodeValue;
|
|
}
|
|
f.setAttribute(atts[i].nodeName, atts[i].nodeValue);
|
|
e.removeAttribute(atts[i].nodeName);
|
|
i--;
|
|
}
|
|
d.appendChild(f);
|
|
this.aSelect = f;
|
|
this.isMultiSelect = f.hasAttribute("isMultiple");
|
|
this.selectedUI = this.createSelectedUI();
|
|
f.appendChild(this.selectedUI);
|
|
var ic = document.createElement("div");
|
|
ic.classList.add("icon", "atg", "a-down-thick");
|
|
f.appendChild(ic);
|
|
this.isSearch = f.hasAttribute("isSearch") && !this.isMultiSelect;
|
|
d.appendChild(this.createSubItemUI());
|
|
this.conSelect = d;
|
|
e.parentNode.insertBefore(d, e);
|
|
this.conSelect = d;
|
|
cselect.appendChild(e);
|
|
this.dropdown.bindDropDowns(f);
|
|
this.scroll = Scrollbar.init(this.cSub, this.o);
|
|
f.setAttribute("data-select-id", this.id);
|
|
this.dropdown.on("opened", function (ev) {
|
|
this.isFocus = true;
|
|
this.isOpen = true;
|
|
if (this.isMultiSelect) {
|
|
this.eleSearch.focus();
|
|
this.listItems.forEach(e => { e.element.classList.remove("hover") });
|
|
this.selectedEleItem = this.listItems[0].element;
|
|
this.listItems[0].element.classList.add("hover");
|
|
}
|
|
}.bind(this));
|
|
this.dropdown.on("closed", function (ev) {
|
|
this.isFocus = false;
|
|
this.isOpen = false;
|
|
if ((this.isSearch && this.isTextSearch) || this.isMultiSelect) {
|
|
this.isTextSearch = false;
|
|
this.eleSearch.value = "";
|
|
this.resetItem(false);
|
|
this.updateHeight();
|
|
}
|
|
if (this.changeIndex) {
|
|
this.trigger("change", this);
|
|
this.changeIndex = false;
|
|
} else {
|
|
this.scroll.scrollIntoView(this.selectedEleItem, {
|
|
offsetTop: 0,
|
|
onlyScrollIfNeeded: true
|
|
});
|
|
}
|
|
}.bind(this));
|
|
if (isTouchAvailable && getOS() === "iOS") {
|
|
e.classList.add("ios");
|
|
}
|
|
var fv1 = function (ev) {
|
|
this.keyDown.call(this, ev);
|
|
}.bind(this);
|
|
e.addEventListener("keydown", fv1, false);
|
|
var fc = function (e) {
|
|
this.subItemClick.call(this, e);
|
|
}.bind(this);
|
|
var f3 = function (ev) {
|
|
ev.preventDefault();
|
|
if (!this.isFocus) {
|
|
window.fireEvent(f, "click");
|
|
this.isFocus = true;
|
|
}
|
|
}.bind(this);
|
|
e.addEventListener("focus", f3, false);
|
|
var f4 = function (ev) {
|
|
ev.preventDefault();
|
|
if (!this.isFocus) {
|
|
this.dropdown.checkCloseDropdown();
|
|
}
|
|
}.bind(this);
|
|
e.addEventListener("blur", f4, false);
|
|
this.scrollSub.addEventListener("click", fc, false);
|
|
}
|
|
subItemClick(e) {
|
|
var p = e.target.closest(".a-option");
|
|
if (p != null && !p.hasAttribute("data-empty")) {
|
|
this.updateIndex(p.getAttribute("index"), true);
|
|
this.dropdown.checkCloseDropdown();
|
|
}
|
|
}
|
|
keyDown(ev) {
|
|
var q = this.selectedEleItem;
|
|
if (ev.keyCode == 40) {
|
|
ev.preventDefault();
|
|
this.changeSearch = true;
|
|
var tmp = q.nextSibling;
|
|
while (tmp != null && tmp.classList.contains("a-option-group")) {
|
|
tmp = tmp.nextSibling;
|
|
}
|
|
if (tmp != null && tmp.classList.contains("a-option")) {
|
|
this.updateIndex(tmp.getAttribute("index"));
|
|
console.log(tmp.offsetTop);
|
|
this.scroll.scrollIntoView(tmp, {
|
|
alignToTop: false,
|
|
offsetBottom: 0,
|
|
onlyScrollIfNeeded: false
|
|
});
|
|
}
|
|
}
|
|
if (ev.keyCode == 38) {
|
|
ev.preventDefault();
|
|
this.changeSearch = true;
|
|
var tmp = q.previousSibling;
|
|
while (tmp != null && tmp.classList.contains("a-option-group")) {
|
|
tmp = tmp.previousSibling;
|
|
}
|
|
if (tmp != null && tmp.classList.contains("a-option")) {
|
|
this.updateIndex(tmp.getAttribute("index"));
|
|
this.scroll.scrollIntoView(tmp, {
|
|
offsetTop: 0,
|
|
onlyScrollIfNeeded: false
|
|
});
|
|
}
|
|
}
|
|
if (ev.keyCode == 13 || ev.keyCode == 9) {
|
|
if (ev.keyCode == 13) ev.preventDefault();
|
|
this.changeSearch = true;
|
|
if (this.eleSearch !== ev.currentTarget && this.isFocus) {
|
|
return;
|
|
}
|
|
if (q.classList.contains("a-option")) {
|
|
this.eleSearch.value = "";
|
|
this.dropdown.checkCloseDropdown();
|
|
this.updateIndex(this.selectedEleItem.getAttribute("index"), true);
|
|
}
|
|
}
|
|
if (ev.keyCode == 8 && this.isMultiSelect) {
|
|
if (this.eleSearch.value.length == 0) {
|
|
if (this.multiSelectedItem.length > 0) {
|
|
var t = this.cSelectedItem.querySelectorAll(".item:not(input)");
|
|
this.removeItem(t[t.length - 1]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
removeItem(ele) {
|
|
var l = this.listItems[ele.getAttribute("data-id")].element;
|
|
l.classList.remove("active");
|
|
this.multiSelectedItem.removeItem(l, this.isItemEqual);
|
|
ele.remove();
|
|
}
|
|
resetItem(f = true) {
|
|
if (this.scrollSub.children.length == 0) return;
|
|
this.scrollSub.removeAll();
|
|
if (this.listGroups.length == 0) {
|
|
for (var i = 0; i < this.listItems.length; i++) {
|
|
this.scrollSub.appendChild(this.listItems[i].element);
|
|
}
|
|
}
|
|
this.scroll.update(true);
|
|
if (this.isMultiSelect && f) {
|
|
var t = this.cSelectedItem.querySelectorAll(".item:not(input)");
|
|
if (t.length > 0) {
|
|
t.removeAll();
|
|
}
|
|
}
|
|
}
|
|
inputSearchEvent(ev) {
|
|
if (this.changeSearch) {
|
|
this.changeSearch = false;
|
|
return;
|
|
}
|
|
this.isTextSearch = true;
|
|
this.scrollSub.removeAll();
|
|
var first = null;
|
|
if (this.listGroups.length == 0) {
|
|
for (var i = 0; i < this.listItems.length; i++) {
|
|
if (this.listItems[i].vSearch.toLowerCase().indexOf(ev.currentTarget.value.toLowerCase()) !== -1) {
|
|
this.scrollSub.appendChild(this.listItems[i].element);
|
|
first = (first == null) ? i : first;
|
|
}
|
|
}
|
|
} else {
|
|
/*arr.sub.querySelectorAll(".a-option-group").forEach(e => e.parentNode.removeChild(e));
|
|
for (var i = 0; i < arr.listEG.length; i++) {
|
|
var d = document.createElement("div");
|
|
d.classList.add("a-option-group");
|
|
d.innerHTML = arr.listEG[i].label;
|
|
arr.sub.appendChild(d);
|
|
var c = true;
|
|
for (var j = 0; j < arr.listEG[i].subitems.length; j++) {
|
|
if (arr.listEG[i].subitems[j].name.toLowerCase().indexOf(ev.target.value.toLowerCase()) !== -1) {
|
|
c = false;
|
|
var tmp = this.addItem(arr.listEG[i].subitems[j]);
|
|
arr.sub.appendChild(tmp);
|
|
first = (first == null) ? tmp : first;
|
|
}
|
|
}
|
|
if (c) d.remove();
|
|
}*/
|
|
}
|
|
if (first != null) {
|
|
this.updateIndex(first);
|
|
}
|
|
else {
|
|
var it = document.createElement("span");
|
|
it.classList.add("ellipsis", "text-center");
|
|
it.innerHTML = "No Result";
|
|
var item = this.itemBaseUI(null, it);
|
|
item.classList.add("d-f", "j-c-center");
|
|
this.scrollSub.appendChild(item);
|
|
item.setAttribute("data-empty", "");
|
|
};
|
|
|
|
this.updateHeight();
|
|
}
|
|
}
|
|
|
|
export default class ASelect extends window.AObject {
|
|
constructor(e) {
|
|
super();
|
|
this.listE = Array.from([]);
|
|
this.listA = [];
|
|
this.el = e;
|
|
this.el.forEach((e) => {
|
|
if (e.nodeName != "SELECT") {
|
|
return;
|
|
}
|
|
this.listA.push(new ASelectEle(e, this.listA.length, this));
|
|
});
|
|
}
|
|
get(id = 0) {
|
|
if (id >= 0 && id < this.listA.length) {
|
|
return this.listA[id];
|
|
} else {
|
|
console.log("error get Aselect");
|
|
}
|
|
}
|
|
getByID(id) {
|
|
for (var i = 0; i < this.listA.length; i++) {
|
|
if (this.listA[i].element.getAttribute("id") == id) {
|
|
return this.listA[i];
|
|
}
|
|
}
|
|
}
|
|
}
|