Fork me on GitHub
#re-frame
<
2017-12-21
>
plins18:12:51

hello everyone, id like to warn the user when trying to leave the page … how can I fire a js/confirm when the onbeforeunload fires?

manutter5118:12:25

I just realized I misunderstood your original question in the #clojurescript channel: you’re not asking about React lifecycle methods, you want the actual basic JavaScript onbeforeunload event built into the document itself.

plins18:12:23

yep! not sure if should use the reagent.core/create-class

manutter5119:12:26

I suspect that as far as the browser is concerned, it’s going to assume that anything in the onbeforeunload handler is a plain vanilla JavaScript function.

manutter5119:12:01

Also I notice at https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload — it says “Since 25 May 2011, the HTML5 specification states that calls to window.alert(), window.confirm(), and window.prompt() methods may be ignored during this event. ”

plins19:12:13

hmm, so thats not going to work .. any suggestions on how to show a confirmation dialog when the users leave?

manutter5119:12:39

It can sorta work, I think

manutter5119:12:31

The trick is that if you assign a string to the returnValue property, the browser will display that string in a popup (under the browser’s control) and give the user a chance to cancel

manutter5119:12:24

You’d need to use CLJS interop stuff to take care of deciding whether or not to return the string, but I think you can mix CLJS and JS enough to query the re-frame db and return either nil or a string, depending on whether the page was “dirty.”

manutter5119:12:38

I’d have to work on that some to figure out the details, but maybe somebody else has done something similar already?

akiroz19:12:26

ohh boy... I've done this before way back in a project I no longer have access to.

akiroz19:12:32

I remember using the react life-cycle methods in the main panel component of that page where the user edits stuff

akiroz19:12:19

on the top, use a let binding for the event handler, in :componentDidMount do addEventListener and on :componentWillUnmount do removeEventListener

akiroz19:12:43

and as suggested in the MDN guide, you need to set both the returnValue and actually return a value of the message you want to display.

akiroz19:12:36

you can just deref a sub in the event handler if you need to check if the page has unsaved changes.

akiroz19:12:10

This is not idiomatic re-frame because you've got a piece of logic in the view but you can't do anything async in the onbeforeunload handler so this will have to be a bit hacky anyway.

akiroz19:12:40

I tried doing this more idiomatically by using an interceptor that detects whether you're entering a page that requires onbeforeunload in your re-frame routing logic and let the interceptor (de)register the handler. Than have the onbeforeunload handler dispatch-sync your re-frame event. The problem with this is that re-frame events can't return a value to the dispatching function which is required by onbeforeunload.

akiroz19:12:07

It aint pretty, better just accept the fact and sprinkle some comments instead of going down the same rabbit hole I did...