Initial import

This commit is contained in:
Admin Nasledstvo
2026-05-01 20:52:04 +03:00
commit ac168868ee
10028 changed files with 2337954 additions and 0 deletions
@@ -0,0 +1,281 @@
class SearchBox {
container
box = document.createElement('div')
list = document.createElement('div')
listItems = document.createElement('div')
selected = document.createElement('div')
searchField = document.createElement('input')
cloneListItems = this.listItems
callback
dynamic = {}
constructor(selector) {
if (typeof selector === "string") {
this.container = document.querySelector(selector)
} else {
this.container = selector;
}
if(this.container) {
if (this.container.nodeName === 'SELECT') {
this.dataRetrieve()
} else {
alert('Html element SELECT is required')
}
addEventListener('keydown', ({keyCode}) => {
if (keyCode === 27) {
this.clear()
}
})
}
}
clear() {
this.box.classList.remove('open')
this.searchField.value = ''
this.listItems.querySelectorAll('.list-item').forEach(e => {
e.classList.add('visible')
e.classList.remove('hover')
e.style.display = 'block'
})
}
getNextSibling(elem, selector) {
var sibling = elem.nextElementSibling;
while (sibling) {
if (sibling.matches(selector)) return sibling;
sibling = sibling.nextElementSibling
}
}
getPreviousSibling(elem, selector) {
var sibling = elem.previousElementSibling;
if (!selector) return sibling;
while (sibling) {
if (sibling.matches(selector)) return sibling;
sibling = sibling.previousElementSibling;
}
}
keyDown() {
this.searchField.addEventListener('keydown', ({keyCode}) => {
if (keyCode === 38 || keyCode === 40) {
event.preventDefault()
const visibleList = this.listItems.querySelectorAll('.visible:not(.hover)');
const firstItem = visibleList[0];
const lastItem = this.listItems.querySelectorAll('.visible:not(.hover)')[visibleList.length - 1];
if (this.listItems.querySelectorAll('.visible.hover').length === 0) {
if (keyCode === 38 && lastItem)
lastItem.classList.add('hover')
if (keyCode === 40 && firstItem)
firstItem.classList.add('hover')
} else {
const hoverElement = this.listItems.querySelector('.visible.hover')
hoverElement.classList.remove('hover')
//up
if (keyCode === 38) {
const prev = this.getPreviousSibling(hoverElement, '.visible')
if (prev && prev.classList.contains('visible')) {
prev.classList.add('hover')
console.log(prev.offsetTop)
this.listItems.scrollTo({
top: prev.offsetTop - 160,
})
} else {
lastItem.classList.add('hover')
this.listItems.scrollTo({
top: lastItem.offsetTop - 160,
})
}
}
//down
if (keyCode === 40) {
const next = this.getNextSibling(hoverElement, '.visible')
if (next && next.classList.contains('visible')) {
next.classList.add('hover')
this.listItems.scrollTo({
top: next.offsetTop - 160
})
} else {
firstItem.classList.add('hover')
this.listItems.scrollTo({
top: firstItem.offsetTop - 160,
})
}
}
}
}
if (keyCode === 13) {
event.preventDefault()
const currentSelected = this.listItems.querySelector('.hover');
if (currentSelected) {
const selected = this.listItems.querySelector('.selected');
if (!this.container.hasAttribute('multiple')) {
if (selected) {
selected.classList.remove('selected')
}
currentSelected.classList.add('selected')
this.selected.innerText = currentSelected.innerHTML
this.container.value = currentSelected.dataset.select
if (this.dynamic.change) {
this.dynamic.change(this.container.value)
}
} else {
this.multipleSelected(currentSelected, this.container.querySelector(`option[value="${currentSelected.dataset.select}"]`))
}
this.container.parentNode.classList.remove('form-error')
this.clear()
}
}
})
}
multipleSelected(listItem, e) {
if (!this.selected.querySelector(`.selected-box[data-id="${e.value}"]`)) {
const sb = document.createElement('div')
const close = document.createElement('div')
sb.className = 'selected-box'
close.className = 'close'
sb.innerText = e.innerText
sb.setAttribute('data-id', e.value)
const sbExists = this.selected.querySelector('.selected-box')
if (!sbExists) {
this.selected.innerHTML = '';
}
sb.appendChild(close)
this.selected.appendChild(sb)
listItem.classList.add('selected')
e.setAttribute('selected', true)
sb.addEventListener('click', () => {
event.preventDefault()
e.removeAttribute('selected')
const listItemSelected = this.listItems.querySelector(`.list-item[data-select="${e.value}"]`)
listItemSelected.classList.remove('selected')
sb.remove()
const sbExists = this.selected.querySelector('.selected-box')
if (!sbExists) {
var s = this.container.querySelector('option:first-child')
if (s)
this.selected.innerHTML = s.innerText;
}
})
}
}
dataRetrieve() {
this.box.classList.add('search-box')
this.list.classList.add('list')
this.selected.classList.add('selected')
this.listItems.classList.add('list-items')
this.list.appendChild(this.searchField)
this.list.appendChild(this.listItems)
this.box.appendChild(this.selected)
this.box.appendChild(this.list)
if (this.container.hasClass('disabled')) {
this.box.classList.add('disabled')
}
this.box.addEventListener('click', e => {
if (
!event.target.classList.contains('selected-box') &&
!event.target.classList.contains('close')
) {
if (this.box.classList.contains('open')) {
this.clear()
} else {
document.querySelectorAll('.search-box').forEach(b => {
b.classList.remove('open')
})
this.box.classList.add('open')
this.searchField.focus()
}
}
})
this.keyDown()
this.updateFromOptionList()
this.searchField.addEventListener('keyup', e => {
this.listItems.querySelectorAll('.list-item').forEach((e, i) => {
if (e.innerText.toLowerCase().indexOf(this.searchField.value.toLowerCase()) !== -1 || this.searchField.value === '') {
e.style.display = 'block'
e.classList.add('visible')
} else {
e.style.display = 'none'
e.classList.remove('visible')
e.classList.remove('hover')
}
})
})
this.container.parentNode.appendChild(this.box);
}
updateFromOptionList() {
this.listItems.innerHTML = '';
this.container.querySelectorAll('option').forEach((e, i) => {
if (i === 0) {
//if (this.selected.innerText !== '')
this.selected.innerText = e.innerText
}
if (e.value) {
const listItem = document.createElement('div');
listItem.className = 'list-item visible'
listItem.setAttribute('data-select', e.value)
listItem.innerText = e.innerText;
this.listItems.appendChild(listItem)
if (e.hasAttribute('selected') && !this.container.hasAttribute('multiple')) {
this.selected.innerText = e.innerText
listItem.classList.add('selected')
this.listItems.scrollTo({
top: listItem.offsetTop - 160,
})
}
if (e.hasAttribute('selected') && this.container.hasAttribute('multiple')) {
this.multipleSelected(listItem, e)
}
listItem.addEventListener('click', l => {
if (!this.container.hasAttribute('multiple')) {
this.container.value = e.value
this.selected.innerText = e.innerText
if (this.dynamic.change) {
this.dynamic.change(this.container.value)
}
} else {
this.multipleSelected(listItem, e)
}
this.container.parentNode.classList.remove('form-error')
})
}
})
}
updateFromObject(object) {
const $this = this;
object.searchBox.dynamic.change = function (value) {
$this.request(object.url, `${object.queryId}=${value}`, data => {
//console.log(data);
$this.container.innerHTML = $this.container.querySelector('option:first-child').outerHTML
data.forEach(o => {
if (o[object.data.id] && o[object.data.name]) {
const option = document.createElement('option')
option.value = o[object.data.id];
option.innerText = o[object.data.name]
$this.container.appendChild(option)
}
})
if (data.length > 0) {
$this.updateFromOptionList()
$this.container.classList.remove('disabled')
$this.box.classList.remove('disabled')
}
})
}
}
request(url, query, callback) {
const xhr = new XMLHttpRequest()
xhr.responseType = 'json'
xhr.open('get', `${url}?${query}`)
xhr.onload = () => {
callback(xhr.response)
}
xhr.send()
}
}