IMPR: Minor fixtures

This commit is contained in:
Tony Air 2024-03-12 01:16:24 +02:00
parent e904381cfd
commit 3d6c6bf603
4 changed files with 82 additions and 38 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@a2nt/ss-bootstrap-ui-webpack-boilerplate-react", "name": "@a2nt/ss-bootstrap-ui-webpack-boilerplate-react",
"version": "5.2.9", "version": "5.3.0",
"description": "This UI Kit allows you to build Bootstrap 5 webapp with some extra UI features. It's easy to extend and easy to convert HTML templates to CMS templates.", "description": "This UI Kit allows you to build Bootstrap 5 webapp with some extra UI features. It's easy to extend and easy to convert HTML templates to CMS templates.",
"author": "Tony Air <tony@twma.pro>", "author": "Tony Air <tony@twma.pro>",
"license": "BSD-2-Clause", "license": "BSD-2-Clause",

View File

@ -22,9 +22,7 @@ const submitForm = (e) => {
data.append('ajax', '1') data.append('ajax', '1')
form.querySelectorAll('.field__alert').forEach((el) => { clearAlerts(form)
el.remove()
})
parent.classList.remove('loaded') parent.classList.remove('loaded')
parent.classList.add('loading') parent.classList.add('loading')
@ -54,6 +52,12 @@ const submitForm = (e) => {
}) })
} }
const clearAlerts = (form) => {
form.querySelectorAll('.field__alert,.form__message').forEach((el) => {
el.remove()
})
}
const processResponse = (html) => { const processResponse = (html) => {
try { try {
let json = JSON.parse(html) let json = JSON.parse(html)
@ -95,27 +99,47 @@ const isAlertResponse = (msg) => {
const formProcessJson = (form, json) => { const formProcessJson = (form, json) => {
const status = json.status === 'good' || 'success' ? 'success' : 'danger' const status = json.status === 'good' || 'success' ? 'success' : 'danger'
if (json.location) {
console.log(`${NAME}: Redirect`)
//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
//}
return setLoaded(form)
}
if (json.msgs) { if (json.msgs) {
const fieldset = form.querySelector('.form__fieldset')
json.msgs.forEach((i) => { json.msgs.forEach((i) => {
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
const field = form.querySelector(`[name="${i.fieldName}"],[name^="${i.fieldName}["]`) const field = form.querySelector(`[name="${i.fieldName}"],[name^="${i.fieldName}["]`)
if (field) { if (field) {
field.classList.add('error') field.classList.add('error')
const fieldContainer = field.closest('.form__field') const fieldContainer = field.closest('.form__field')
if (fieldContainer) { if (fieldContainer) {
fieldContainer.classList.add('error') fieldContainer.classList.add('error')
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
fieldContainer.appendChild(msg) fieldContainer.appendChild(msg)
return
} }
} }
form.insertBefore(msg, fieldset)
}) })
return setLoaded(form) return setLoaded(form)

View File

@ -5,14 +5,15 @@ const PasswordUI = ((window) => {
const init = () => { const init = () => {
console.log(`${NAME}: init`) console.log(`${NAME}: init`)
let timer
let timer;
const toggle = (input) => { const toggle = (input) => {
if (input.getAttribute('type') === 'password') { console.log(`${NAME}: toggle`)
show(input) if (timer) {
} else { clearTimeout(timer);
hide(input)
} }
show(input)
} }
const show = (input) => { const show = (input) => {
@ -24,18 +25,18 @@ const PasswordUI = ((window) => {
const hide = (input) => { const hide = (input) => {
input.setAttribute('type', 'password') input.setAttribute('type', 'password')
if(timer){ if (timer) {
clearTimeout(timer); clearTimeout(timer);
} }
} }
document.querySelectorAll(`${NAME}-show, .show-password`).forEach((el) => { document.querySelectorAll(`${NAME}-show, .show-password`).forEach((el) => {
if(el.classList.contains(`${NAME}-active`)){ if (el.classList.contains(`${NAME}-active`)) {
return return
} }
el.addEventListener('click', (e) => { el.addEventListener('click', (e) => {
const input = e.currentTarget.closest('.field').querySelector('input'); const input = e.currentTarget.closest('.field').querySelector('input')
if (!input) { if (!input) {
return return
} }

View File

@ -1,52 +1,71 @@
import Events from '../_events' import Events from '../_events'
const NAME = 'uiTurnstile' const NAME = 'uiTurnstile'
const SELECTOR = '.cf-turnstile' const SELECTOR = `.${NAME},.js-turnstile`
const init = () => { const init = () => {
console.log(`${NAME}: init`)
const captchas = document.querySelectorAll(SELECTOR) const captchas = document.querySelectorAll(SELECTOR)
if (!captchas.length) { if (!captchas.length) {
console.log(`${NAME}: No Captcha fields.`) console.log(`${NAME}: No Captcha fields.`)
return return
} }
if (typeof window.turnstile === 'undefined') { if (!document.querySelector('#captchaAPI') && typeof window.turnstile === 'undefined') {
loadScript(init) loadScript(init)
return return
} }
console.log(`${NAME}: init`) renderCaptcha()
}
const renderCaptcha = () => {
console.log(`${NAME}: renderCaptcha`)
const captchas = document.querySelectorAll(SELECTOR)
captchas.forEach((el) => { captchas.forEach((el) => {
if (el.dataset[NAME] || el.innerHTML.length > 0) { if (el.dataset[NAME] || el.innerHTML.length > 0) {
if (el.dataset.widgetid) {
turnstile.reset(el.dataset.widgetid)
}
return return
} }
window.turnstile.render(el) const widgetid = window.turnstile.render(el, {
sitekey: el.dataset.sitekey,
callback: function (token) {
console.log(`${NAME}: Challenge Success ${token}`);
},
})
const form = el.closest('form')
form.addEventListener('submit', () => {
console.log(`${NAME}: submit`)
window.turnstile.reset(el.dataset.widgetid)
})
el.dataset.widgetid = widgetid
el.dataset[NAME] = true el.dataset[NAME] = true
}) })
} }
const loadScript = () => {
window.turnstileFieldRender = init
const loadScript = (callback) => {
if (typeof window.turnstile !== 'undefined') {
callback()
}
console.log(`${NAME}: Loading Captcha API ...`) console.log(`${NAME}: Loading Captcha API ...`)
const script = document.createElement('script'); const script = document.createElement('script');
script.id = 'captchaAPI'; script.id = 'captchaAPI';
script.src = `https://challenges.cloudflare.com/turnstile/v0/api.js?hl=${document.querySelector('html').getAttribute('lang').substr(0, 2)}` script.src = `https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit&onload=renderCaptcha&hl=${document.querySelector('html').getAttribute('lang').substr(0, 2)}`
script.async = true script.async = true
script.onload = function () {
console.log(`${NAME}: Turnstile Captcha API is loaded.`)
callback()
}
document.body.append(script) document.body.append(script)
} }
window.renderCaptcha = renderCaptcha
window.addEventListener(`${Events.LODEDANDREADY}`, init) window.addEventListener(`${Events.LODEDANDREADY}`, init)
window.addEventListener(`${Events.AJAX}`, init) window.addEventListener(`${Events.AJAX}`, init)