pkp/pkp-lib — comment on commit 50620d60a4c9e9563e9dd85f79150640115e1f22
File: js/controllers/form/FormHandler.js line 60
By beghelli:

Hi Jason. I think that, if we are going to use the beforeunload event (I think it's necessary), we don't have other option, we need to bind it to the window element. I think that the solution, in this case, is to use a higher level widget to bind only one event handler that will work to all forms. This widget could be the site, see SiteHandler.js.

Firstly, I think we need to better specify the use cases that this feature has. I can think of two, right now:
1- a form is changed and the user tries to load another page;
2- a form is changed inside a modal and the user tries to close the modal;

I think that could be more, but I didn't spent too much time on this yet. But let's consider those two cases. Here is a general idea that I think will work well, even with more cases:

1 - keep the beforeunload event handler in Site handler.
2 - allow every widget that has a form widget as child know if this form has changed data (we can do this by creating a new event and triggering it every time the formChange handler, in form handler, is called). Knowing if a form has changed data inside of it, all widgets that needs to handle with the 'don't leave the page without saving' feature will have the chance to do it. I think that the ModalHandler and SiteHandler will need implement some code for this feature.

Note that the modal handler needs to create a handler for the formDataChanged (or something like that) and publish this event too, so it gives a chance for the site to know that a form has changed data too.

With this implemented, I think it will work like this for our use cases:

1 - a form is changed and the user tries to load another page: the site will always bind the beforeunload event to the window. But, when this event handler is called on every redirect request, the site will have the information if there is (or was) a child form with changed data. Then, on the beforeunload event handler, the site can check this information to decide if it needs to present the message to user or not. I think that this forms changed data information in site will need to be stored in array, using the form html element id, so the site can check, for many forms necessary, if the html form element is still present on screen or not.

2 - a form is changed inside a modal and the user tries to close the modal: the modal will know, when the user tries to close it, if it has forms with unsaved data inside of it. So, it can show or not the message to user too.

3 - a form is changed inside a modal and the user tries to load another page: this is covered by the use case 1, I think.

The problem with the download redirections triggering the beforeunload event I think we can resolve by checking some data in request that can identify a file download, and then don't show any message to user even if there is a form with unsaved data. But I am not sure if it is possible. Maybe this is a best start point, because we cannot use the beforeunload event until this is resolved.

I didn't spent too much time thinking about the other issues, and I don't have a hundred percent sure about what I wrote here. Usually I need to code a little to see if things will work as I thought. :P But I think that those ideas can help you.

Again, if you need any help, just let me know.