Detekce opuštění formuláře (presenteru) bez uložení

jedlicka
Člen | 61
+
0
-

Ahoj,

mám formulář pro založení klienta (presenter RecordPresenter) a potřeboval bych detekovat, že uživatel opouští vyplňování formuláře před jejím uložením (např. chce přejít do jiného presenteru), a zobrazit alert/modal, zda opravdu chce odejít bez uložení formuláře nebo formulář uložit.

Děkuji za každou radu.

Martin

nightfish
Člen | 468
+
+1
-

@jedlicka V JavaScriptu se pověsit na event beforeunload

m.brecher
Generous Backer | 713
+
-3
-

Ne ne, beforeunload v javascriptu není moc dobrá cesta.

Lepší je navěsit ovladač na událost click přímo na celý DOM prohlížeče a ošetřit ty kliky, které by vedly na opuštění stránky – tj. všechny kliknutí na odkazy, které vedou na jiné než aktuální url. V ovladači se optat, zda chce uživatel skutečně odejít bez odeslání nedokončeného formuláře.

Kód cca takovýto:

<script>
    document.addEventListener('click', handleClick);
    function handleClick(event)
    {
        const elem = event.target;
        if(elem.nodeName === 'A'){
            let leave = window.confirm('Skutečně odejít? Ve formuláři jsou neuložená data !!!');
            if(!leave){
                event.preventDefault();
            }
        }
    }
</script>

Kód jsem testoval a funguje, ale bude potřeba do profesionálního průmyslového nasazení ho doladit!

Kód nezabrání odejití uživatele posunem v prohlížeči na předchozí stránku, nebo vypnutí prohlížeče. To ani z principu prohlížeče neumožňují nějak blokovat a beforeunload s tím nic nenadělá ;).

m.brecher
Generous Backer | 713
+
0
-
  • samozřejmě ošetřit případy, kdy odkaz jenom roluje stránku jinam a pokud by na stránce byly jiné formuláře tak to bude už složitější. Je-li ale na stránce jeden formulář, odkazy jsou všechny html a nepoužívá se rolování stránky html odkazy (url#anchor), tak ten kód se dá rovnou takhle nasadit.
Michalek
Člen | 209
+
+2
-

Tak zaprvé si myslím, že onbeforeunload funguje i na zavření prohlížeče i na tlačítko zpět, druhak bych jakoukoliv událost nevěšel hned na onload, ale až po interakci s formulářem. Rozhodně nechci vlézt na stránku s formulářem, nic v něm neudělat a dostávat hlášku…

m.brecher
Generous Backer | 713
+
0
-

Michalek napsal(a):

Tak zaprvé si myslím, že onbeforeunload funguje i na zavření prohlížeče i na tlačítko zpět, druhak bych jakoukoliv událost nevěšel hned na onload, ale až po interakci s formulářem. Rozhodně nechci vlézt na stránku s formulářem, nic v něm neudělat a dostávat hlášku…

Ne, na tlačítko zpět nedám ruku do ohně, ale na zavření prohlížeče je onbeforeunload krátký a javascript se utne okamžitě. Jediné co lze v javascriptu ještě udělat je odeslat nějaká statistická data o opuštění stránky, určitě nejde manipulovat se stránkou natož nějaký alert či to přesměrovat jinam. Ví se o tom poměrně málo, ale kdysi jsem to testoval a je to tak.

Při zavření prohlížeče onbeforeunload nevykoná vůbec nic (záleží na prohlížeči) a jde použít jedině navigator.sendBeacon()

https://developer.mozilla.org/…r/sendBeacon

Ano, normy html říkají co má onbeforeunload/onunload dělat, ale prohlížeče respektují navíc ještě bezpečnostní a výkonnostní hlediska. I jenom nevhodný způsob odesílání statistických dat by mohlo zdržovat přechod na další stránku, nehledě na zneužitelnost různými nekonečnými alerty v cyklu.

Co se týče detekce zda formulář blokovat či ne, to je potřeba samozřejmě do javascriptu doplnit. Ideální je si v javascriptu cyklem vytvořit kopii struktury formulářových prvků a v onclicku navíc kontrolovat, zda se data ve formuláři změnily nebo ne. Teprve když víme, že se data změnily poslat uživateli dotaz zda odejít. To je celkem samozřejmé.

Editoval m.brecher (9. 2. 2022 20:46)