initial files
This commit is contained in:
89
public/javascript/requiredFields.js
Normal file
89
public/javascript/requiredFields.js
Normal file
@@ -0,0 +1,89 @@
|
||||
function createRequiredProgress({ container, progress, onChange }) {
|
||||
let total = 0;
|
||||
let filled = 0;
|
||||
|
||||
const body = typeof container === 'string'
|
||||
? document.querySelector(container)
|
||||
: container;
|
||||
|
||||
const progressEl = typeof progress === 'string'
|
||||
? document.querySelector(progress)
|
||||
: progress;
|
||||
|
||||
if (!body || !progressEl) return;
|
||||
|
||||
function isElementVisible(el) {
|
||||
const style = window.getComputedStyle(el);
|
||||
return el.offsetParent !== null && style.opacity !== '0';
|
||||
}
|
||||
|
||||
function updateRequiredProgress() {
|
||||
const requiredElements = Array.from(
|
||||
body.querySelectorAll('input[required], select[required], textarea[required]')
|
||||
).filter(isElementVisible);
|
||||
|
||||
total = requiredElements.length;
|
||||
filled = requiredElements.filter(el =>
|
||||
el.classList.contains('is-required-filled')
|
||||
).length;
|
||||
|
||||
progressEl.textContent = `${filled} / ${total} Pflichtfelder ausgefüllt`;
|
||||
progressEl.classList.toggle('complete', filled === total);
|
||||
progressEl.classList.toggle('incomplete', filled !== total);
|
||||
}
|
||||
|
||||
function updateRequiredState(el) {
|
||||
const isEmpty =
|
||||
(el instanceof HTMLSelectElement && !el.value) ||
|
||||
(el instanceof HTMLInputElement && el.type !== 'checkbox' && !el.value.trim()) ||
|
||||
(el instanceof HTMLTextAreaElement && !el.value.trim());
|
||||
|
||||
el.classList.toggle('is-required-empty', isEmpty);
|
||||
el.classList.toggle('is-required-filled', !isEmpty);
|
||||
|
||||
updateRequiredProgress();
|
||||
|
||||
if (typeof onChange === 'function') {
|
||||
onChange({
|
||||
element: el,
|
||||
isEmpty,
|
||||
isFilled: !isEmpty,
|
||||
isFinished: total === filled
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function initialize() {
|
||||
const elements = Array.from(
|
||||
body.querySelectorAll('input[required], select[required], textarea[required]')
|
||||
).filter(isElementVisible);
|
||||
|
||||
elements.forEach(el => {
|
||||
updateRequiredState(el);
|
||||
|
||||
el.addEventListener('input', () => updateRequiredState(el));
|
||||
el.addEventListener('change', () => updateRequiredState(el));
|
||||
});
|
||||
|
||||
updateRequiredProgress();
|
||||
}
|
||||
|
||||
// 🔥 Reagiere auf Sichtbarkeitsänderungen
|
||||
const observer = new MutationObserver(updateRequiredProgress);
|
||||
observer.observe(body, {
|
||||
attributes: true,
|
||||
subtree: true,
|
||||
attributeFilter: ['style', 'class', 'hidden']
|
||||
});
|
||||
|
||||
initialize();
|
||||
|
||||
// Optional: API zurückgeben
|
||||
return {
|
||||
initialize: initialize,
|
||||
refresh: updateRequiredProgress,
|
||||
destroy() {
|
||||
observer.disconnect();
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user