Request now without obligation

How can we help you?

How can we reach you?

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