diff --git a/resources/js/portal-form-hooks.js b/resources/js/portal-form-hooks.js index 3e945f98..142d4e6a 100644 --- a/resources/js/portal-form-hooks.js +++ b/resources/js/portal-form-hooks.js @@ -25,11 +25,13 @@ let scrollPending = false; // Selektoren für Buttons, die wir als "Submit-Intent" interpretieren. + // Bewusst NICHT '[wire\\:submit]': das matcht das
selbst, und da + // Klicks bubbeln, würde jeder Klick in irgendein Feld den Scroll armieren + // (Bug 08.07.: USt-ID-Live-Check sprang zum ersten Feld hoch). const SUBMIT_SELECTORS = [ '[wire\\:click*="save"]', '[wire\\:click*="submit"]', '[wire\\:click*="update"]', - '[wire\\:submit]', 'button[type="submit"]', ].join(','); @@ -40,6 +42,14 @@ } }, true); + // Enter-Submit in wire:submit-Forms kommt nicht als Button-Klick an — + // das submit-Event deckt ihn ab (Livewire preventet nur den Default). + document.addEventListener('submit', (event) => { + if (event.target.matches('[wire\\:submit]')) { + scrollPending = true; + } + }, true); + document.addEventListener('livewire:init', () => { if (!window.Livewire || typeof window.Livewire.hook !== 'function') { return; @@ -53,9 +63,13 @@ scrollPending = false; requestAnimationFrame(() => { + // Flux rendert unter JEDEM Feld einen (hidden) Error-Container + // mit Whitespace-Inhalt — ':not(:empty)' matcht den daher auch + // ohne Fehler. Nur Container mit echtem Text zählen. const invalid = document.querySelector('[data-flux-control][aria-invalid="true"]') || document.querySelector('[aria-invalid="true"]') - || document.querySelector('[data-flux-error]:not(:empty)'); + || Array.from(document.querySelectorAll('[data-flux-error]')) + .find((el) => el.textContent.trim() !== ''); if (!invalid) { return;