Fork me on GitHub

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?


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.


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


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.


Also I notice at — 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. ”


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


It can sorta work, I think


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


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.”


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


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


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


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


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.


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


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.


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.


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