Files
register/marko_unpacked/marko/cms/_public/assets/js/inner-table-items.js
T
Admin Nasledstvo ac168868ee Initial import
2026-05-01 20:52:04 +03:00

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()
}
}
}