Remote Synthesis
Search my blog:
Viewing By Entry / Main
Apr 03, 2009

Using jQuery to Confirm Cancel Changes on a Form

Those of you who follow this blog know that I have spent much of my recent time in Flex. However, recently I have had to toy with jQuery (again) for a project. Hopefully this will be the first in a series of tutorial posts regarding jQuery - though there are a plethora of them already out there.

In this example I had a large form displayed and the cancel button would clear the form and return to a prior view. Since you could potentially change information and either forget or inadvertently click the cancel button, I thought it would be best to confirm when you cancel. Still, I don't want to confirm the cancel if you didn't actually change anything. In the end, I used jQuery to easily attach events to my entire form to indicate if you changed anything and jQuery UI to display a friendly warning dialog before proceeding with the cancel process.

For the purposes of this example I have distilled the code (posted below) into a simple HTML page that a basic form and the cancel dialog along with the JavaScript necessary. The first thing I did was set a boolean flag, which I call "formWasChanged," to false. Within my init method (which is just called when the document is done loading), I add a change listener to every input field on the page that will call my formWasChanged() method and simply set this flag to true. jQuery makes it extremely easy to add this listener to all elements of your form since the selector ":input" matches "all input, textarea, select and button elements."

The next step is to simply add a click handler for the cancel button, which is the cancelFormAlert() method. The cancelFormAlert() method checks to see if the flag is true (i.e. you tripped the forms change handlers) and, if so, it displays a jQuery UI dialog that I created int the init method. The properties of that dialog are pretty straightforward to configure, but in this case you will want to ensure that it doesn't display automatically (i.e. autoOpen: false) and will likely want to set it to modal (i.e. modal: true). The dialog references a Div which I have placed at the bottom of the page. Note that the div has a "display: none" CSS property which I used to remove any lag that caused the HTML to render before the dialog() script was run.

Obviously the final part of this would be to actually perform the cancel by clearing the form and/or opening the new page, but that should be pretty straightforward and will change depending on the nature of your form. Still, it is nice that jQuery makes this task relatively easy to do.

<html>
<head>
   <title>jQuery Confirm Cancel Example</title>

   <link type="text/css" href="jquery/css/smoothness/jquery-ui-1.7.1.custom.css" rel="stylesheet" />
   <script type="text/javascript" src="jquery/js/jquery-1.3.2.min.js"></script>
   <script type="text/javascript" src="jquery/js/jquery-ui-1.7.1.custom.min.js"></script>

   <script type="text/javascript">
   var formChanged = false;

   function init() {
      $(":input").change(formWasChanged);
      $("[name=cancelForm]").click(cancelFormAlert);
      $("#confirmCancelDialog").dialog({
         autoOpen: false,
         bgiframe: true,
         resizable: false,
         height: 140,
         modal: true,
         overlay: {
            backgroundColor: '#000',
            opacity: 0.5
         },
         buttons: {
            'Proceed?': function(){
               $(this).dialog('close');
               // do something
            },
            Cancel: function(){
               $(this).dialog('close');
            }
         }
      });
   }

   function formWasChanged() {
      formChanged = true;
   }

   function cancelFormAlert() {
      if (formChanged == true) {
         $("#confirmCancelDialog").dialog("open");
      }
      else {
         // do something
      }
   }

   $(document).ready(init);
   </script>
</head>
<body style="font-family: Arial,Verdana,sans-serif;font-size: 11px;">
<form onsubmit="return false;">
   <label for="firstName">First Name</label>: <input name="firstName" size="50" /><br />
   <label for="firstName">Last Name</label>: <input name="lastName" size="50" /><br />
   <input type="submit" name="submitForm" value="Submit" />&amp;nbsp;
   <input type="button" name="cancelForm" value="Cancel" />
</form>

<div id="confirmCancelDialog" title="Confirm Cancel" style="display:none;">
   <p><span class="ui-icon ui-icon-alert" style="float:left; margin:0 7px 20px 0;"></span>Are you sure you want to cancel? Any changes will be lost.</p>
</div>
</body>
</html>

Comments
anthony
Really cool stuff.

You should look into using the jQuery live event for binding events to elements (http://docs.jquery.com/Events/live). The problem with binding change events on DOM load is that if the page is quite long, you could have people editting the form before the dom is actually ready. I realize that this is an edge case, but I have run into instances where I used jQuery to bind an event to a search box on a product listing page that listed over a hundred items.


Write your comment



(it will not be displayed)