Initial import
This commit is contained in:
@@ -0,0 +1,210 @@
|
||||
class SelectorBase {
|
||||
find(selector, parent) {
|
||||
const p = parent || document
|
||||
return parent.querySelector(selector)
|
||||
}
|
||||
|
||||
findAll(selector, parent, callback) {
|
||||
const p = parent || document,
|
||||
result = parent.querySelectorAll(selector)
|
||||
result.forEach((e, i) => {
|
||||
callback(e, i)
|
||||
})
|
||||
return result;
|
||||
}
|
||||
|
||||
set(obj) {
|
||||
obj = obj || {};
|
||||
const element = document.createElement(obj.tagName || 'div')
|
||||
if (obj.type) element.type = obj.type
|
||||
if (obj.className) element.className = obj.className
|
||||
if (obj.innerHTML) element.innerHTML = obj.innerHTML
|
||||
if (obj.name) element.name = obj.name
|
||||
if (obj.value) element.value = obj.value
|
||||
if (obj.events) {
|
||||
Object.keys(obj.events).forEach(event => {
|
||||
element.addEventListener(event, e => {
|
||||
obj.events[event](element)
|
||||
})
|
||||
})
|
||||
}
|
||||
if (obj.attributes) {
|
||||
Object.keys(obj.attributes).forEach(attr => {
|
||||
element.setAttribute(attr, obj.attributes[attr])
|
||||
})
|
||||
}
|
||||
if (obj.parent) obj.parent.appendChild(element)
|
||||
return element
|
||||
}
|
||||
|
||||
toggleClass(e, classFrom, classTo) {
|
||||
e.classList.remove(classFrom)
|
||||
e.classList.add(classTo)
|
||||
}
|
||||
|
||||
toggleOpen(e) {
|
||||
if (e.classList.contains('open-autocomplete')) {
|
||||
e.classList.remove('open-autocomplete')
|
||||
} else {
|
||||
e.classList.add('open-autocomplete')
|
||||
}
|
||||
}
|
||||
|
||||
request(url, query, callback) {
|
||||
const xhr = new XMLHttpRequest()
|
||||
xhr.responseType = 'json'
|
||||
xhr.open('get', `${url}?${query}`)
|
||||
xhr.onload = () => {
|
||||
callback(xhr.response)
|
||||
}
|
||||
xhr.send()
|
||||
}
|
||||
}
|
||||
|
||||
class SearchBoxRemote extends SelectorBase {
|
||||
constructor(selector, obj) {
|
||||
super();
|
||||
this.set({
|
||||
tagName: 'link',
|
||||
parent: document.head,
|
||||
attributes: {href: '/_public/assets/css/search-box-remote.css', rel: 'stylesheet'}
|
||||
})
|
||||
document.querySelectorAll(selector).forEach(element => {
|
||||
new SearchBoxRemoteInitial(element, obj)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
class SearchBoxRemoteInitial extends SelectorBase {
|
||||
url
|
||||
q
|
||||
id
|
||||
columns
|
||||
selected
|
||||
hidden
|
||||
searchBoxContainer
|
||||
inputSearch
|
||||
autocompleteList
|
||||
|
||||
constructor(selector, obj) {
|
||||
super();
|
||||
obj = obj || {};
|
||||
this.url = obj.url || null
|
||||
this.q = obj.q || 'q'
|
||||
this.id = obj.id || 'id'
|
||||
this.columns = obj.columns || null
|
||||
this.init(selector)
|
||||
}
|
||||
|
||||
init(e) {
|
||||
if (e.dataset && e.dataset.sbrName) {
|
||||
this.hidden = this.set({
|
||||
tagName: 'input',
|
||||
type: 'hidden',
|
||||
name: e.dataset.sbrName,
|
||||
value: e.dataset.sbrValue,
|
||||
parent: e.parentNode
|
||||
})
|
||||
e.setAttribute('readonly', true)
|
||||
e.classList.add('pointer')
|
||||
e.parentNode.classList.add('relative')
|
||||
this.selected = e
|
||||
e.addEventListener('click', () => {
|
||||
this.setSearchBox(e.parentNode)
|
||||
})
|
||||
this.setDefaultSelected()
|
||||
}
|
||||
}
|
||||
|
||||
setSearchBox(container) {
|
||||
if (container.classList.contains('open-autocomplete')) {
|
||||
container.classList.remove('open-autocomplete')
|
||||
container.querySelector('.search-box-container').remove()
|
||||
} else {
|
||||
this.searchBoxContainer = this.set({className: 'search-box-container', parent: container})
|
||||
this.inputSearch = this.set({
|
||||
tagName: 'input', attributes: {
|
||||
class: 'input-search',
|
||||
placeholder: 'Търси ...',
|
||||
}, parent: this.searchBoxContainer
|
||||
})
|
||||
this.inputSearch.focus();
|
||||
if ((window.innerHeight - this.searchBoxContainer.getBoundingClientRect().top) < 500) {
|
||||
this.searchBoxContainer.classList.add('up-position')
|
||||
this.setAutocompleteList('prepend')
|
||||
} else {
|
||||
this.searchBoxContainer.classList.add('down-position')
|
||||
this.setAutocompleteList('append')
|
||||
}
|
||||
container.classList.add('open-autocomplete')
|
||||
}
|
||||
}
|
||||
|
||||
setAutocompleteList(type) {
|
||||
this.autocompleteList = this.set({className: 'autocomplete-list'})
|
||||
if (type === 'prepend') this.searchBoxContainer.insertBefore(this.autocompleteList, this.inputSearch)
|
||||
if (type === 'append') this.searchBoxContainer.append(this.autocompleteList)
|
||||
this.inputSearch.addEventListener('keydown', () => {
|
||||
this.keyDown()
|
||||
})
|
||||
this.inputSearch.addEventListener('keyup', () => {
|
||||
this.keyUp()
|
||||
})
|
||||
}
|
||||
|
||||
setDefaultSelected() {
|
||||
if(this.hidden.value) {
|
||||
this.request(this.url, `${this.id}=${this.hidden.value}`, e => {
|
||||
if(e.settlement_id) {
|
||||
this.selected.value = `${e.name}`;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
setAutocompleteValues(data) {
|
||||
const $this = this
|
||||
this.autocompleteList.innerHTML = ''
|
||||
data.forEach(e => {
|
||||
const resultRow = this.set({
|
||||
className: 'autocomplete-value',
|
||||
innerHTML: `${e.name}`,
|
||||
parent: this.autocompleteList,
|
||||
events: {
|
||||
click: function () {
|
||||
$this.hidden.value = e.settlement_id;
|
||||
$this.searchBoxContainer.parentNode.classList.remove('open-autocomplete')
|
||||
$this.searchBoxContainer.remove();
|
||||
$this.selected.value = resultRow.innerHTML
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
keyDown() {
|
||||
this.autocompleteList.innerHTML = ''
|
||||
}
|
||||
|
||||
keyUp() {
|
||||
if (this.inputSearch.value.length > 0) {
|
||||
this.request(this.url, `${this.q}=${this.inputSearch.value}`, data => {
|
||||
if (data && data.length > 0) {
|
||||
this.setAutocompleteValues(data)
|
||||
this.autocompleteList.classList.add('visible')
|
||||
} else {
|
||||
this.closeAutocomplete()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.closeAutocomplete()
|
||||
}
|
||||
}
|
||||
|
||||
closeAutocomplete() {
|
||||
this.autocompleteList.classList.remove('visible')
|
||||
this.autocompleteList.innerHTML = ''
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user