Request now without obligation
document.addEventListener('DOMContentLoaded', function () {
const formIdInput = document.querySelector('form.elementor-form input[name="form_id"]');
const form = formIdInput ? formIdInput.closest('form.elementor-form') : null;
if (!form) return;
form.setAttribute('novalidate', 'novalidate');
const getSteps = () => Array.from(form.querySelectorAll('.e-form__step'));
const getActiveStep = () => getSteps().find(step => !step.classList.contains('elementor-hidden'));
const getNextButton = (step) =>step ? step.querySelector('.e-form__buttons__wrapper__button-next') : null;
const getSubmitButton = (step) =>step ? step.querySelector('button[type="submit"]') : null;
function isRadioGroupValid(step) const radios = Array.from(step.querySelectorAll('input[type="radio"]'));
const groupNames = [...new Set(radios.map(r => r.name).filter(Boolean))];
return groupNames.every(name =>radios.some(r => r.name === name && r.checked)
);
function isFieldValid(field) {
if (!field || field.disabled || field.type === 'hidden') return true;
const type = (field.type || '').toLowerCase();
if (type === 'radio') return true;
if (type === 'checkbox') return !field.required || field.checked;
if (type === 'file') {
if (field.required && (!field.files || field.files.length === 0)) return false;
return field.checkValidity();
}
if (field.tagName === 'SELECT') return !field.required || field.value.trim() !== '';
if (field.required && !field.value.trim()) return false;
return field.checkValidity();
}
function isStepValid(step) if (!step) return false;
const radiosOk = isRadioGroupValid(step);
const otherFields = Array.from(
step.querySelectorAll('input:not([type="radio"]):not([type="hidden"]), textarea, select')
);
const othersOk = otherFields.every(isFieldValid);
return radiosOk && othersOk;
function setButtonState(button, enabled) if (!button) return;
button.disabled = !enabled;
button.toggleAttribute('disabled', !enabled);
button.setAttribute('aria-disabled', enabled ? 'false' : 'true');
button.classList.toggle('is-disabled', !enabled);
function updateButtons() {
getSteps().forEach(step => const valid = isStepValid(step);
const nextButton = getNextButton(step);
const submitButton = getSubmitButton(step);
setButtonState(nextButton, valid);
setButtonState(submitButton, valid);
);
}
form.addEventListener('click', function (e) {
const option = e.target.closest('.elementor-field-option');
if (!option || !form.contains(option)) return;
if (e.target.closest('label, input, a, button')) return;
const input = option.querySelector('input[type="radio"], input[type="checkbox"]');
if (!input) return;
if (input.type === 'radio') {
if (!input.checked) {
input.checked = true;
input.dispatchEvent(new Event('change', bubbles: true ));
}
} else {
input.checked = !input.checked;
input.dispatchEvent(new Event('change', bubbles: true ));
}
});
form.addEventListener('input', updateButtons);
form.addEventListener('change', function (e) {
updateButtons();
const field = e.target;
const activeStep = getActiveStep();
if (
activeStep &&
field.matches('input[type="radio"]') &&
activeStep.contains(field) &&
isStepValid(activeStep)
) {
const nextButton = getNextButton(activeStep);
if (nextButton && !nextButton.disabled) setTimeout(() => nextButton.click(), 120);
}
});
form.addEventListener('click', function (e) {
if (e.target.closest('[data-direction="next"], [data-direction="previous"]')) setTimeout(updateButtons, 50);
setTimeout(updateButtons, 150);
});
const observer = new MutationObserver(() => updateButtons());
getSteps().forEach(step => {
observer.observe(step, attributes: true,
attributeFilter: ['class']
);
});
form.addEventListener('submit', function (e) {
const allStepsValid = getSteps().every(isStepValid);
if (!allStepsValid) e.preventDefault();
updateButtons();
});
// Wichtig: mehrfach initial prüfen, weil Elementor oft später nochmal rendert
updateButtons();
setTimeout(updateButtons, 50);
setTimeout(updateButtons, 250);
setTimeout(updateButtons, 600);
window.addEventListener('load', function () updateButtons();
setTimeout(updateButtons, 100);
);
});
“Every project starts with an idea—let’s talk about it.”
Contact person
Lorem Ipsum