2

I have a js change event which saves data via an Ajax request when a user leaves a control. This works fine unless the user decides to leave the page. The Ajax then does not complete and the data is not saved. Looking at Ajax request with JQuery on page unload I see that if I make the request synchronous the Ajax request will complete. I have tried this and it does work. However, I am calling this change event whenever the user moves from control to control on the page and I do not want all these calls to be synchronous.

I tried using Alert for unsaved changes in form to check for unsaved data. This triggers the beforeunload function fine when there is a control with unsaved data, however I can't work out what to put in the beforeunload function.

  • I can put in an alert. When the user cancels the alert my change code runs and all is fine. However, it is annoying and confusing for the user to have a dialog box pop up when normally data is saved without them having to do anything
  • I tried Using jQuery to test if an input has focus to find the element which has focus and then force my change function to run on this. However, I couldn't find an element with focus (may have been doing something wrong here?)
  • I tried using a sleep function to give the Ajax call time to run but that didn't work either
  • I tried setting the focus into another control - no luck

Any ideas about what else I might try or what I might be doing wrong with any of the things I've tried? Can I somehow have an invisible alert that is triggered and cancelled without the user having to do anything?

Community
  • 1
  • 1
Rachel Edge
  • 351
  • 2
  • 6
  • 18
  • 2
    There isn't a reliable way to do this, for very good reason: If an Ajax request could cause the browser to wait before leaving the page, then a clever site could make it impossible to leave the page for an indefinite period of time. That could, and would, be abused by bad actors. Izzey's advice below is good. Design your application with the assumption that the user could leave, or their internet connection could be lost, at any given time. Read up on [Offline First!](http://offlinefirst.org/) for more best practices. – Jordan Running Oct 06 '14 at 19:04

2 Answers2

3

The only good solution to save data when the user leaves the page is to continiously save data offline (localStorage) and alert the user if the data hasn't been saved to the server when they leave the page. The good thing about localStorage is that the data is saved to the browser even when the computer crashes or the connection is lost. When the user reconnects you can sync data back to the server.
More about offline browser storage:
https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Storage
http://diveintohtml5.info/storage.html

orhanhenrik
  • 1,407
  • 8
  • 11
  • This sounds great but would require too much of a re-write to be possible at the moment. Long term I plan to set up an offline version of my site .. but that will have to wait. – Rachel Edge Oct 07 '14 at 13:03
1

Trigger a SEPARATE ajax call that is synchronous in an unload function. This way when the page goes to unload, the second AJAX call (that is blocking) will fire, and the page will not unload until the save is complete, and your original asynchronous AJAX call will remain for the rest of the use of the page

Mark
  • 861
  • 9
  • 17
  • I tried creating a separate synchronous call but I make more than one Ajax call during the save, the first to check for duplicate values and the second to save the data. I could get the first to run but not the second. – Rachel Edge Oct 07 '14 at 13:04
  • Did you make both calls during the save as synchronous calls? If you don't want to do that, you could chain them with jQuery callbacks, on success of the first call => execute second call. – Mark Oct 07 '14 at 13:05
  • Yes the calls are within jQuery callbacks but it calls one then gets to the next and doesn't execute the call. I'll have another look and see if I can see what is going on. – Rachel Edge Oct 07 '14 at 13:10
  • 1
    That now works - I'd made a syntax error in making the call synchronous. So I now set a flag in my `beforeunload` routine which sets my Ajax calls to synchronous, call the save routine on my control, which I saved to a variable when it got focus, and 'Bob's your uncle'. – Rachel Edge Oct 07 '14 at 15:00