Warning APEX Users of Form Changes on Navigation away from the page.

Doug Gault APEX 10 Comments

It has come to my attention the the link back to this article that originally appeared on the Enkitec.com web site is broken. Knowing that people still find this useful, I’ve copied it here so that it can be easily found and referenced.


It’s a common problem. A user spends time entering data into a form and then, for some reason, clicks a button or tab that will navigate away from the form without saving his data. Wouldn’t it be nice if there were a way to warn the user that the data hasn’t been saved, and that they may lose their work?Well, there actually is a way to do this in JavaScript, and you don’t have to do a lot of work yourself. Here’s how…

The following JavaScript is the key for Standard APEX Forms. You can include it either in the HTML HEADER of the page, or in an HTML Region on the page:

<script type="text/javascript">

function onChangeinit() {

// This function sets up those fields in <strong>STANDARD APEX FORMS</strong>
// which should trigger the "Are You Sure" Popup box upon
// navigating away from the page.
// First set up the array of elements in the form
// This method uses JavaScript to create an array of elements.

var fields = document.getElementById('wwvFlowForm').elements;

// Now loop through the array and assign the on-change event
// The onchange function sets the value of a JavaScript variable
// to '1' to show that something has changed.

for (var i=0; i<fields.length; i++) {
$x(fields[i]).onchange = function () {
window.unsaved=1;
}
}
}

// Now Set up the UNSAVED variable
// and the function that checks it on UNLOAD.

window.unsaved = '';
window.onbeforeunload = function() {
return window.unsaved ? 'There may be unsaved changes to your data.' : undefined;
}
// And you're done.
</script>

For APEX Tabular Forms, the code needs to change just a bit to cover all the iterations of the fields on the page:

<script type="text/javascript">

function onChangeinit() {

// This function sets up those fields for a <strong>TABULAR FORM</strong>
// which should trigger the "Are You Sure" Popup box upon navigating
// away from the page.

// First set up the array of elements in the form
// This method uses JavaScript to create an array of elements.

var fields = document.getElementById('wwvFlowForm').elements;

// Now loop through the array and see if the id matches the format f99_9999
// If it does, assign the on-change event.
//
// The onchange function sets the value of a JavaScript variable
// to '1' to show that something has changed.

for (var i=0; i<fields.length; i++)
if (fields[i].id.match('^f[0-9]{2}_{1}[0-9]{4}$'))
{
$x(fields[i]).onchange = function () {window.unsaved=1;}
}
}

// Now Set up the UNSAVED variable
// and the function that checks it on UNLOAD.

window.unsaved = '';
window.onbeforeunload = function() {
return window.unsaved ? 'There may be unsaved changes to your data.' : undefined;
}

// And you're done.
</script>

The onChangeinit JavaScript function needs to be run whenever the page loads. To do that, we call it by placing the following JavaScript in the Execute when Page Loads attribute at the page level.

onChangeinit();

Finally, we want to provide a way to short circuit this for instances where we want them to be able to press a button without getting the message. The most common example of this would be the SAVE button. Again, you can include it either in the HTML HEADER of the page, or in an HTML Region on the page.

<script type="text/javascript">
function preSubmit() {
// Call this before any action where you want the user
// to be able to navigate without the warning message.
// For instance, add this to the BUTTON ATTRIBUTES of the
// SAVE button of your form.

window.unsaved='';
}
</script>

The last thing to do is edit any buttons that we want to be able to submit the page without being warned and make sure they call the preSubmit JavaScript function.

To make this change to SUBMIT buttons, edit the button and do the following:

• In the Action When Button Pressed region, change the Action to Redirect to URL
• in the URL Target enter the following:

javascript:preSubmit();apex.submit('<ButtonName>');

Make sure the that <ButtonName> in the code above is actually the name of the button that you’re editing. That way when the apex.submit JavaScript function is called, it will be as if the user pressed the button.

For the DELETE buttons, edit the button and do the following:

• In the Action When Button Pressed region, change the Action to Redirect to URL
• in the URL Target enter the following:

javascript:preSubmit();apex.confirm(htmldb_delete_message,'<ButtonName>');

Again, make sure the that <ButtonName> in the code above is actually the name of the button that you’re editing.

That’s it. That’s all there is to it. The nice thing about this is that it will even catch changes made by other JavaScript.

 

Comments 10

  1. This is awesome!!.

    The only negative side affect I have is when navigating away via
    the tabs across the top the warning message pops up twice. Any idea why this function would be being called twice in this scenario?

  2. Hmm.. Not sure about this. I'd try to use the Javascript debugger in your browser to see what's going on.

    If you're using APEX 5.0+ then this trick isn't really necessary any more as 5.X automatically checks to see if you're navigating away before saving changes.

  3. Thanks for responding so promptly.
    We are still on 4.2.3.xx however we are looking to upgrade in the future.
    Good to know this is not required once we upgrade.
    Thanks again.

  4. Hi Doug! I am in 5.1.3 but have a textarea that I use a Dynamic Action to update the users input and I give a success message but it was giving the message as I tried to navigate away.
    I added your preSubmit with a name change..
    function doNotShowChangesMayNotBeSaved() {
    window.unsaved=”;
    }
    and called it in a JavaScript TRUE action “before” my PL/SQL TRUE action and it worked great!
    If I add text and try to navigate away I still get the warning as I desire.

    The only problem is that if I enter text in the textarea and try to navigate away, I get the warning and select STAY so I can click my button to save the text. When I select STAY the page shows the spinner and does not allow anything but a reload of the page.
    Do you know how to kill the spinner?

    Thank you,
    Bill Carlisle

    1. Post
      Author

      Hey Bill,

      Good to hear from you!

      Is it possible for you to throw up a quick example on apex.oracle.com so I can have a look at what it might be doing. I’m not sure what’s causing the spinner to hang, so would need to look at what’s going on (JS wise) on the page that might be colliding.

      Happy to have a look at it but I would want to make sure the setup I was reproducing the issue correctly.

      1. Hey Doug, Was trying to reproduce it on APEX site and couldn’t so I just selected the “Warn on Unsaved Changes” to “No” under “Navigation” for page attributes.
        Thank you for spending the time to help others! You are very appreciated.

        Happy APEXing,
        Bill Carlisle

        1. Post
          Author
  5. Hey Dough ,

    Above example works good when tabular form has text field and dropdowns but does not recognize when there is change in checkbox. What code should be added inorder to have JS to identify when the change is made to checkbox.

    1. Post
      Author

      Pravan,

      How are the Checkboxes being generated. Would it be possible for you to create an example on apex.oracle.com so i can see how they’re being generated?

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.