webpack-bootstrap-ui-kit/src/js/ajax/form.js

212 lines
4.8 KiB
JavaScript
Raw Normal View History

2023-11-20 11:20:58 +01:00
import Events from '@a2nt/ss-bootstrap-ui-webpack-boilerplate-react/src/js/_events'
const NAME = 'uiAjaxForm'
const CONTAINER_CLASS = 'form-container'
const submitForm = (e) => {
const form = e.currentTarget
e.preventDefault()
console.log(`${NAME}: submit`)
const data = new FormData(form);
const parent = form.parentElement;
const btns = form.querySelectorAll('input[type="submit"],button')
2024-02-02 17:20:06 +01:00
const id = form.getAttribute('ID')
btns.forEach((el) => {
el.setAttribute('disabled', 'disabled')
})
2024-02-02 17:20:06 +01:00
data.append('formid', id)
2023-11-20 11:20:58 +01:00
data.append('ajax', '1')
2023-11-22 03:08:58 +01:00
2024-02-02 22:24:41 +01:00
2024-03-12 00:16:24 +01:00
clearAlerts(form)
2024-02-02 22:24:41 +01:00
2023-11-22 03:09:54 +01:00
parent.classList.remove('loaded')
parent.classList.add('loading')
2023-11-20 11:20:58 +01:00
fetch(form.action, {
method: form.method,
headers: {
'x-requested-with': 'XMLHttpRequest',
2024-02-02 17:20:06 +01:00
'x-requested-form': id,
2023-11-20 11:20:58 +01:00
},
body: data,
})
.then(async (resp) => {
2024-02-02 22:24:41 +01:00
if (!resp.ok) {
console.error(`${NAME}: BAD RESPONSE`)
console.log(resp)
return
}
2023-11-20 11:20:58 +01:00
const body = resp.text().then((html) => {
2024-02-02 22:24:41 +01:00
const result = processResponse(html)
if (result.json) {
return formProcessJson(form, result.data)
}
2024-02-02 15:31:10 +01:00
2024-02-02 22:24:41 +01:00
return replaceForm(form, result.data)
})
})
}
2024-02-02 15:31:10 +01:00
2024-03-12 00:16:24 +01:00
const clearAlerts = (form) => {
form.querySelectorAll('.field__alert,.form__message').forEach((el) => {
el.remove()
})
}
2024-02-02 22:24:41 +01:00
const processResponse = (html) => {
try {
let json = JSON.parse(html)
2023-11-20 11:20:58 +01:00
2024-02-02 22:24:41 +01:00
if (json.MainContent) {
try {
json = JSON.parse(json.MainContent)
2023-11-20 11:20:58 +01:00
2024-02-02 22:24:41 +01:00
return {
json: true,
2024-02-02 22:25:22 +01:00
data: json,
2023-11-20 11:20:58 +01:00
}
2024-02-02 22:24:41 +01:00
} catch (e) {
return {
json: false,
2024-02-02 22:25:22 +01:00
data: json.MainContent,
2024-02-02 22:24:41 +01:00
}
}
}
return {
json: true,
2024-02-02 22:25:22 +01:00
data: json,
2024-02-02 22:24:41 +01:00
}
} catch (e) {
return {
json: false,
2024-02-02 22:25:22 +01:00
data: html,
2024-02-02 22:24:41 +01:00
}
}
}
2024-03-07 12:47:22 +01:00
const isAlertResponse = (msg) => {
return msg.indexOf('class="alert') || msg.indexOf('class=\'alert')
}
2024-02-02 22:24:41 +01:00
const formProcessJson = (form, json) => {
2024-03-07 12:47:22 +01:00
const status = json.status === 'good' || 'success' ? 'success' : 'danger'
2024-02-02 22:24:41 +01:00
2024-03-12 00:16:24 +01:00
if (json.location) {
console.log(`${NAME}: Redirect`)
2024-03-12 00:31:35 +01:00
if (!json.loadAjax && typeof window.app.Router !== 'undefined') {
const link = document.createElement('a')
link.setAttribute('href', json.location)
window.app.Router.linkClick(link, new Event('click'))
} else {
window.location = json.location
}
2024-03-12 00:16:24 +01:00
return setLoaded(form)
}
2024-02-02 22:24:41 +01:00
if (json.msgs) {
2024-03-12 00:16:24 +01:00
const fieldset = form.querySelector('.form__fieldset')
2024-02-02 22:24:41 +01:00
json.msgs.forEach((i) => {
2024-03-12 00:16:24 +01:00
const msg = document.createElement('div')
msg.classList.add(...['field__alert'])
if (!isAlertResponse(i.message)) {
msg.classList.add(...['alert', `alert-${status}`, `alert-${i.messageCast}`, `${i.messageType}`])
}
msg.innerHTML = i.message
2024-03-07 12:47:22 +01:00
const field = form.querySelector(`[name="${i.fieldName}"],[name^="${i.fieldName}["]`)
2024-03-12 00:16:24 +01:00
2024-02-02 22:24:41 +01:00
if (field) {
field.classList.add('error')
const fieldContainer = field.closest('.form__field')
if (fieldContainer) {
fieldContainer.classList.add('error')
fieldContainer.appendChild(msg)
2024-03-12 00:16:24 +01:00
return
2024-02-02 22:24:41 +01:00
}
}
2024-03-12 00:16:24 +01:00
form.insertBefore(msg, fieldset)
2023-11-20 11:20:58 +01:00
})
2024-02-02 22:24:41 +01:00
return setLoaded(form)
}
2024-03-07 12:47:22 +01:00
const replacementHTML = !isAlertResponse(json.message)
? `<div class="alert alert-${status}">${json.message}</div>`
: json.message
return replaceForm(form, replacementHTML)
2024-02-02 22:24:41 +01:00
}
const setLoaded = (form) => {
const parent = form.parentElement;
parent.classList.remove('loading')
parent.classList.add('loaded')
const btns = form.querySelectorAll('input[type="submit"],button')
btns.forEach((el) => {
el.removeAttribute('disabled', 'disabled')
})
window.dispatchEvent(new Event(`${Events.AJAX}`))
2023-11-20 11:20:58 +01:00
}
const replaceForm = (form, html) => {
const parent = form.parentElement;
2023-11-22 02:37:58 +01:00
parent.innerHTML = html
parent.classList.remove('loading')
parent.classList.add('loaded')
2023-11-20 11:20:58 +01:00
2024-02-02 22:24:41 +01:00
const newForm = parent.querySelector('form')
if (newForm) {
newForm.addEventListener('submit', submitForm)
return setLoaded(newForm)
}
2023-11-20 11:20:58 +01:00
}
const formInit = (form) => {
if (form.dataset[`${NAME}Active`]) {
console.log(`${NAME}: #${form.id} already activated`)
return false
}
2023-11-22 02:37:58 +01:00
// wrap form
const parent = form.parentElement;
if (!parent.classList.contains(CONTAINER_CLASS)) {
const elHtml = document.createElement('div')
elHtml.classList.add(CONTAINER_CLASS)
elHtml.append(form)
2023-11-22 02:57:02 +01:00
parent.append(elHtml)
2023-11-22 02:37:58 +01:00
}
//
2023-11-20 11:20:58 +01:00
form.dataset[`${NAME}Active`] = true
form.addEventListener('submit', submitForm)
}
const init = () => {
console.log(`${NAME}: init`)
2024-02-02 15:31:10 +01:00
document.querySelectorAll('#MainContent form:not(.legacy),.ajax-form').forEach(formInit)
2023-11-20 11:20:58 +01:00
}
window.addEventListener(`${Events.LODEDANDREADY}`, init)
window.addEventListener(`${Events.AJAX}`, init)