Tuesday, December 30, 2008

Wait, Wait! Don't forget to save...

Ever want to display a warning message to your users if they try to leave a page without saving their changes? Until I took a look at this forum post, I'd never really thought much about how to implement this functionality. But with jQuery and Jon St. John's code to help me get started, it wasn't too hard.

The trick is creating reusable/generic code and the following is a start toward that end. Please let me know of any issues/suggestions so that I can make updates. Also, keep in mind that this should not be implemented on VERY page - just the important ones! ;)

I "retrofitted" this previous example to demonstrate. Try modifying a value in the form and then use one of the links on the left to leave the page - even try closing the page. Notice the buttons still work as they should.

Here's how to get it working...

  1. Install jQuery in ApEx.
  2. Place the following code in the HTML Header of the page.
    
     

34 comments:

  1. It doesn't work with Opera 9 :(

    ReplyDelete
  2. Algimas,

    I just did a little digging and apparently this is on Opera. It doesn't support onbeforeunload...

    Regards,
    Dan

    ReplyDelete
  3. dan, thanks for this post.
    this however does not handle the window close event. when a change is made and the user closes the browser, this will prompt...right ?
    is there a technique to capture that too ?

    thanks
    n

    ReplyDelete
  4. Neelesh Shah,

    I'm a little confused by what you mean but I'll say this... The unbeforeunload event fires before onclose. Once you get to onclose, it's too late for any interaction. And yes, if the user makes a change and tries to close the browser they should be prompted.

    If that doesn't help, send me an email and I'll try to better answer your question.

    Regards,
    Dan

    ReplyDelete
  5. Dan...Thanks for a quick response. I am going to solely blame this on Folgers, lack of it in my bloodstream.

    It works, of course.
    Thanks Again
    Neelesh

    ReplyDelete
  6. Thanks Dan,
    Its working sweet on my Apex form page, however if I have changed data and click on the date picker its prompting with the message. Is there a way to skip the data change check when user clicks on date picker icon ?

    Thanks 'n Regards
    Ligon

    ReplyDelete
  7. Ligon,

    That's strange, I added specific code to keep that from happening. What browser are you using?

    Look here and see if it happens...
    http://www.shellprompt.net/pls/apex/f?p=566:11

    Regards,
    Dan

    ReplyDelete
  8. Hi Dan

    I have replicated my page on apex.oracle and it now looks working good.

    Thanks for your time and the great codes you provide.

    You are a life saver my friend.

    I have also tried the date picker, its working but looks to be misaligned. Great if you could have a quick look and comment.

    http://apex.oracle.com/pls/otn/f?p=JQueryDatePicker2

    ligon_apex, test, test123

    Many Thanks and Regards
    Ligon

    Regards
    Ligon

    ReplyDelete
  9. Ligon,

    This is fairly common and most of the time is left alone. I modified flora. datepicker.css to align the image properly. Make sure to do a ctrl + F5 to refresh the css.

    img.ui-datepicker-trigger {
    margin-top: 0px;
    margin-bottom: 3px;
    margin-left: 2px;
    vertical-align: middle;
    }

    Regards,
    Dan

    ReplyDelete
  10. Dan, Thanks for this code. I used it in a form and it works perfect. But when I try it in a report (I have a SQL report with just one check box / row, the rest of the columns are standard text), it only works when I leave the page but not during pagination. When I click on next/previous, it does not prompt me with the alert message. What am I doing wrong ? Thanks a lot
    Neelesh

    ReplyDelete
  11. Neelesh,

    I see that now - it happens if partial page refresh is enabled for the report. I plan to revisit this code over the weekend. I'll see if I can get that taken care of.

    Regards,
    Dan

    ReplyDelete
  12. Neelesh,

    Unfortunately ApEx does not yet have a mechanism to bind events after a page is updated via the partial page render. jQuery's live event was almost enough to make up for the shortcoming but it does not yet support the "change" event.

    For now you'll just have to disable partial page rendering for the report. I'll update the post when this obstacle has been overcome.

    Regards,
    Dan

    ReplyDelete
  13. Thanks a lot Dan. I will disable the PPR for these reports.

    Thanks for yours posts. Makes development interesting.
    Neelesh

    ReplyDelete
  14. Dan - have you tried this with IE7? I am getting the double pop-up mentioned in some of the posts where they are using standard javascript.
    Thanks,
    Steve

    ReplyDelete
  15. Steve,

    Yes, it works in IE7. What do you mean by standard JavaScript? Do you mean another solution?

    I'm actually planning a few enhancements for this code...

    Regards,
    Dan

    ReplyDelete
  16. Hi Dan,
    The javascript I refer to you can find several hits in the forum searching for "WarnSave".

    The problem:
    using IE - change a field and exit without saving - onbeforeunload popup fires, user clicks OK, the same popup fires, user clicks OK - then gets out. In FF you exit with the first OK.

    Second issue:
    The popup fires when you upload a file and when you click the standard "Create" button on a form page - which is confusing for the user.

    Thanks,
    Steve

    ReplyDelete
  17. Steve,

    Have you used the test or had any problems with it? This code should already takes care of the issues you mentioned.

    There is one problem where the user will get a double warning if they click a second level tab in IE6 (maybe 7) but I already have a fix for that.

    I'll be releasing that fix along with better handling of template based buttons soon.

    Regards,
    Dan

    ReplyDelete
  18. Dan,
    I am using the code (copied and pasted into the HTML page header - and pointed to the jquery js in the page template) you post here and seeing the problems I describe. The only thing I can think of is the version of JQuery (jquery-1.3.2.min.js) - could that be the problem?

    Steve

    ReplyDelete
  19. Steve,

    Please email me offline. I'll be happy to help you figure out what's not working but we need a better communication medium. ;)

    Regards,
    Dan

    ReplyDelete
  20. Dan, I found a problem in IE6 with this script, the alert pops up two times. FF works fine though. Have you encountered this before ?
    Thanks
    Neelesh

    ReplyDelete
  21. Neelesh,

    Yes, it's something that I've fixed but want to get the template buttons working better first. Email me offline if you want it sooner.

    Regards,
    Dan

    ReplyDelete
  22. I couldn't find the download for the pack version, only dev and prod (min) and couldn't get the prod one to work. After getting it to work, if I click "Apply Changes" button in my app, the message pops up. Why would it pop-up for when "Apply Changes" is clicked.

    Thanks,
    Drew

    ReplyDelete
  23. Drew,

    Not sure what you mean about the pack and min versions...

    As for the button, are you using template based buttons? That's probably what's causing the problem.

    Depending on which template based buttons you're using the code can be easily modified to work with them.

    Regards,
    Dan

    ReplyDelete
  24. Yes, I'm using template based buttons. Can you give me pointers on how to customize the code for the template base buttons?

    ReplyDelete
  25. Drew,

    You just have to modify line 8 so that the jQuery selector works for your buttons.

    From:
    var $templateButtons = $(':button[class]');

    To something like:
    var $templateButtons = $('.t13ButtonAlternative1');

    You'll need to look at your button templates to see exactly how they are set up.

    Regards,
    Dan

    ReplyDelete
  26. In your instructions for downloading jquery, "pack" is not an option afer 1.2.6, only prod(min) and dev(uncompressed). That is the pain in having a technology blog, keeping up with all the technology changes. :)

    I did get the app to work with HTML, buttons, but I really don't want to change all my buttons if I can tweak the code. It looks like the current code as something in it for templateButtons, but I guess it needs more

    thanks,
    Drew

    ReplyDelete
  27. Drew,

    See my last comment, I gave you some pointers. There are different kinds of template based buttons. Some are just buttons that have a class applied to them others really aren't buttons at all.

    The code that's there for template buttons only takes care of the former. The other buttons must be taken care of manually as their exact implementation can vary a lot.

    Regards,
    Dan

    ReplyDelete
  28. I'm just using the standard Template Button and Button for theme 12. This is what is in the template def: href="#LINK#" class="t12Button">#LABEL#

    I changed the button to Alternative 1, and put in your suggestion, but it didn't work. I tried several other combinations, but still no dice.

    How do I figure out what it's called, what the variable is set to? Do I need to dig into code? Is there anyplace it's displayed?

    ReplyDelete
  29. How can I find out their exact implementation?

    ReplyDelete
  30. Drew,

    Please email me offline.

    Regards,
    Dan

    ReplyDelete
  31. Hi Dan,

    I was testing the demo application. If I make a change in a cell, and then close the window, it will not prompt to save.

    However, if I make a change and click out of the cell where the change was made, the alert pop-ups when trying to close the window.

    Is this expected?

    ReplyDelete
  32. Keisha,

    Good catch, I modified lines 11-13 as follows:

    $items.bind("change keyup", function() {
    itemChanged = true;
    });

    I'll update the blog entry at a later date.

    Regards,
    Dan

    ReplyDelete