362 lines
13 KiB
JavaScript
362 lines
13 KiB
JavaScript
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.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)
|
|
}
|
|
}
|
|
|
|
class InnerTableItems extends SelectorBase {
|
|
updateUrl
|
|
|
|
constructor() {
|
|
super();
|
|
this.setDefault()
|
|
}
|
|
|
|
setChangeToSelect(e) {
|
|
this.typeValueSelectorChange(e, e.name.replace('user_interface_type', 'select_data'))
|
|
}
|
|
|
|
setChangeDataType(e) {
|
|
console.log(e.value)
|
|
}
|
|
|
|
setUpdateUrl(url) {
|
|
this.updateUrl = url;
|
|
}
|
|
|
|
setDefault() {
|
|
this.findAll('.type-value-selector', document, e => {
|
|
e.addEventListener('change', () => {
|
|
this.typeValueSelectorChange(e, e.name.replace('user_interface_type', 'select_data'))
|
|
})
|
|
})
|
|
this.findAll('.inner-td-table .add-row', document, e => {
|
|
e.addEventListener('click', () => {
|
|
this.addNewRow(e)
|
|
})
|
|
})
|
|
this.findAll('.inner-td-table .remove', document, e => {
|
|
e.addEventListener('click', () => {
|
|
this.deleteRow(e)
|
|
})
|
|
})
|
|
this.findAll('.inner-td-table .add-bg, .inner-td-table .add-en', document, e => {
|
|
e.addEventListener('keydown', () => {
|
|
this.addNewRow(e)
|
|
})
|
|
})
|
|
this.findAll('.inner-td-table .update-bg, .inner-td-table .update-en', document, e => {
|
|
e.addEventListener('keydown', () => {
|
|
this.updateRow(e)
|
|
})
|
|
e.addEventListener('blur', () => {
|
|
this.updateRow(e)
|
|
})
|
|
})
|
|
}
|
|
|
|
addNewRow(e) {
|
|
const erd = this.eventRetrieveData(e)
|
|
if (erd) {
|
|
const lg = !erd.inputEn ? 1 : null;
|
|
const row = this.setRow(erd.tbody, erd.dataTable, 'update', lg)
|
|
row.inputBg.value = erd.inputBg.value
|
|
if (row.inputEn && erd.inputEn) {
|
|
row.inputEn.value = erd.inputEn.value
|
|
}
|
|
if(erd.inputBg.value !== '') {
|
|
if (erd.tbody.dataset.id !== 'undefined') {
|
|
console.log(erd.tbody.dataset.id)
|
|
if (this.updateUrl && erd.tbody.dataset.id) {
|
|
erd.tr.classList.add('disabled')
|
|
this.request({
|
|
url: this.updateUrl,
|
|
data: {
|
|
parent_id: erd.tbody.dataset.id,
|
|
bg: erd.inputBg.value,
|
|
en: erd.inputEn ? erd.inputEn.value : '',
|
|
},
|
|
success: r => {
|
|
if (r.id) {
|
|
row.tr.setAttribute('data-option-id', r.id);
|
|
erd.tbody.insertBefore(row.tr, erd.tr)
|
|
erd.inputBg.value = ''
|
|
if (erd.inputEn) erd.inputEn.value = ''
|
|
erd.tr.classList.remove('disabled')
|
|
erd.inputBg.focus()
|
|
this.setData(erd.tbody, erd.hidden)
|
|
flash.success('Опцията е добавена успешно')
|
|
} else {
|
|
flash.error('Опцията не беше добавена поради грешка в системата')
|
|
}
|
|
}
|
|
})
|
|
}
|
|
} else {
|
|
erd.tbody.insertBefore(row.tr, erd.tr)
|
|
erd.inputBg.value = ''
|
|
if (erd.inputEn) erd.inputEn.value = ''
|
|
erd.tr.classList.remove('disabled')
|
|
erd.inputBg.focus()
|
|
this.setData(erd.tbody, erd.hidden)
|
|
}
|
|
} else {
|
|
errorElement(erd.inputBg, 'Стойността не може да бъде празна')
|
|
}
|
|
}
|
|
}
|
|
|
|
updateRow(e) {
|
|
const erd = this.eventRetrieveData(e)
|
|
if (erd) {
|
|
if(erd.tr && erd.tr.dataset.optionId) {
|
|
erd.tr.classList.add('disabled');
|
|
this.request({
|
|
url: this.updateUrl,
|
|
data: {
|
|
id: erd.tr.dataset.optionId,
|
|
bg: erd.inputBg.value,
|
|
en: erd.inputEn ? erd.inputEn.value : '',
|
|
},
|
|
success: r => {
|
|
if(r.id) {
|
|
this.setData(erd.tbody, erd.hidden)
|
|
flash.success('Опцията е актуализирана успешно')
|
|
} else {
|
|
flash.error('Опцията не беше актуализирана поради грешка в системата')
|
|
}
|
|
erd.tr.classList.remove('disabled');
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
deleteRow(e) {
|
|
const erd = this.eventRetrieveData(e)
|
|
if (erd) {
|
|
erd.tr.classList.add('disabled');
|
|
if(erd.tr && erd.tr.dataset.optionId) {
|
|
this.request({
|
|
url: this.updateUrl,
|
|
data: {
|
|
id: erd.tr.dataset.optionId,
|
|
remove: 1
|
|
},
|
|
success: r => {
|
|
if(r.success) {
|
|
erd.tr.remove()
|
|
this.setData(erd.tbody, erd.hidden)
|
|
flash.success('Опцията е премахната успешно')
|
|
} else {
|
|
flash.error('Опцията не беше премахната поради грешка в системата')
|
|
erd.tr.classList.remove('disabled')
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
setRow(tbody, dataTable, type, lg) {
|
|
const trObj = {tagName: 'tr', attributes: {"data-table": dataTable}};
|
|
if (type === 'add')
|
|
trObj.parent = tbody
|
|
const
|
|
tr = this.set(trObj),
|
|
tdBg = this.set({tagName: 'td', parent: tr}),
|
|
inputBg = this.set({
|
|
tagName: 'input',
|
|
parent: tdBg,
|
|
className: `${type}-bg`,
|
|
events: {
|
|
keydown: () => {
|
|
if (type === 'add')
|
|
this.addNewRow(inputBg)
|
|
if (type === 'update')
|
|
this.updateRow(inputBg)
|
|
}
|
|
}
|
|
}),
|
|
|
|
tdEn = this.set({tagName: 'td', parent: tr}),
|
|
inputEn = this.set({
|
|
tagName: 'input',
|
|
parent: tdEn,
|
|
className: `${type}-en`,
|
|
events: {
|
|
keydown: () => {
|
|
if (type === 'add')
|
|
this.addNewRow(inputEn)
|
|
if (type === 'update')
|
|
this.updateRow(inputEn)
|
|
}
|
|
}
|
|
})
|
|
|
|
if (lg === 1) tdEn.remove()
|
|
|
|
|
|
const button = this.set({
|
|
tagName: 'td',
|
|
className: type === 'add' ? 'add-row' : 'remove',
|
|
parent: tr,
|
|
innerHTML: `<i class="la la-${type === 'add' ? 'plus' : 'remove'}"></i>`,
|
|
events: {
|
|
click: () => {
|
|
if (type === 'add')
|
|
this.addNewRow(button)
|
|
if (type === 'update')
|
|
this.deleteRow(button)
|
|
}
|
|
}
|
|
})
|
|
if (type === 'add')
|
|
inputBg.focus()
|
|
if (type === 'update') {
|
|
tr.className = 'added-row'
|
|
tr.setAttribute('data-table', dataTable)
|
|
}
|
|
return {tr, inputBg, inputEn};
|
|
|
|
}
|
|
|
|
eventRetrieveData(e) {
|
|
if (event.keyCode && event.keyCode !== 13) return
|
|
var tr = "";
|
|
if (event.keyCode === 13) event.preventDefault()
|
|
if (e.tagName === "INPUT") tr = e.parentNode.parentNode
|
|
if (e.tagName === "TD") tr = e.parentNode
|
|
const
|
|
dataTable = tr.dataset.table,
|
|
tbody = document.querySelector(`.inner-td-table[data-table="${dataTable}"] tbody`),
|
|
hidden = document.querySelector(`input[name="${dataTable}"]`),
|
|
button = this.find('.add-row', tr),
|
|
inputBg = this.find('td:nth-child(1) input', tr),
|
|
inputEn = this.find('td:nth-child(2) input', tr)
|
|
return {dataTable, tr, inputBg, inputEn, tbody, hidden, button}
|
|
}
|
|
|
|
setData(tbody, hidden) {
|
|
const data = []
|
|
this.findAll('.added-row', tbody, (e, i) => {
|
|
e.setAttribute('data-index', i)
|
|
const objectRow = {};
|
|
const bg = this.find('td:nth-child(1) input', e)
|
|
const en = this.find('td:nth-child(2) input', e)
|
|
if(e.dataset.optionId) objectRow['id'] = e.dataset.optionId
|
|
if (bg) objectRow['bg'] = bg.value
|
|
if (en) objectRow['en'] = en.value
|
|
data.push(objectRow)
|
|
})
|
|
hidden.value = JSON.stringify(data)
|
|
return data
|
|
}
|
|
|
|
request(o) {
|
|
console.log(o);
|
|
const xhr = new XMLHttpRequest()
|
|
xhr.responseType = 'json'
|
|
xhr.onload = () => {
|
|
if(o.success) {
|
|
o.success(xhr.response)
|
|
}
|
|
}
|
|
xhr.open('post', o.url)
|
|
const fd = new FormData()
|
|
if(o.data) {
|
|
Object.keys(o.data).forEach(key => {
|
|
fd.append(key, o.data[key])
|
|
})
|
|
}
|
|
xhr.send(fd)
|
|
}
|
|
|
|
typeValueSelectorChange(elem, dataTable) {
|
|
const
|
|
existHidden = elem.parentNode.querySelector('input[type="hidden"]'),
|
|
existTable = elem.parentNode.querySelector('table.inner-td-table')
|
|
|
|
if(existHidden) existHidden.remove()
|
|
if(existTable) existTable.remove()
|
|
|
|
if (elem.value === 'list') {
|
|
const
|
|
hidden = this.set({tagName: 'input', type: 'hidden', name: dataTable}),
|
|
table = this.set({
|
|
tagName: 'table',
|
|
className: 'inner-td-table',
|
|
innerHTML:
|
|
`<thead>
|
|
<tr><td>стойност (bg)</td><td>стойност (en)</td><td></td></tr>
|
|
</thead>`,
|
|
attributes: {"data-table": dataTable}
|
|
}),
|
|
tbody = this.set({tagName: 'tbody', parent: table, attributes: {"data-id": elem.dataset.id}})
|
|
this.setRow(tbody, dataTable, 'add')
|
|
elem.parentNode.appendChild(hidden)
|
|
elem.parentNode.appendChild(table)
|
|
} else if (elem.value === 'list_simple') {
|
|
const
|
|
hidden = this.set({tagName: 'input', type: 'hidden', name: dataTable}),
|
|
table = this.set({
|
|
tagName: 'table',
|
|
className: 'inner-td-table',
|
|
innerHTML:
|
|
`<thead>
|
|
<tr><td>стойност</td></tr>
|
|
</thead>`,
|
|
attributes: {"data-table": dataTable}
|
|
}),
|
|
tbody = this.set({tagName: 'tbody', parent: table, attributes: {"data-id": elem.dataset.id}})
|
|
this.setRow(tbody, dataTable, 'add', 1)
|
|
elem.parentNode.appendChild(hidden)
|
|
elem.parentNode.appendChild(table)
|
|
} else {
|
|
const
|
|
hidden = this.find('input[type="hidden"]', elem.parentNode),
|
|
table = this.find('table.inner-td-table', elem.parentNode)
|
|
if (hidden) hidden.remove()
|
|
if (table) table.remove()
|
|
}
|
|
}
|
|
}
|