Blogs from the Ranch

< Back to Our Blog

Dirty Forms

When building fancy AJAXy apps that have complex user flows outside of page navigation, it’s important to let users know if they are about to trash something they just wrote. Ever had a browser lose several paragraphs of text you typed in? Not fun!

This can be done as complexly as you want, but at Highgroove we’re big fans of KISS so here’s a simple approach to making this happen. It assumes you’re using jQuery, but the same technique should work with any other JavaScript framework.

  1. When your form changes, note that somewhere. An easy way to do this is to latch on to the ‘change’ event for all form elements for forms you want to protect (in this case with the CSS class ‘track_dirty’), and store that in a global variable:

    var formDirty = false; $(‘form.track_dirty *’).change( function(){ window.formDirty = true; });

You could store this as an attribute on the form, or even store the details about what changed on each element, but that gets complicated quick.

  1. When the user tries to do something that hides the form or takes them to another place, let them know whats going on. Because we know when a form is dirty from #1, we just intercept the click event and return false unless the user confirms that they want to continue. Some code:

    $(‘a.scope_changer’).click( function() { if ( window.formDirty ) { if (confirm(“You have unsaved changes. Switching tabs will lose these! Continue?”)) { window.formDirty = undefined; $(‘form’).each(function(i, o) { o.reset(); } ) } else { return false; } } });

You don’t have to reset all the form elements, but if you’ve told a user that they might lose changes and they come back to the tab/frame/etc and see their changes still there, they might be a little confused! In this example we listen to anchor elements classed with ‘scope_changer’ but you could do this on any other HTML element that changes a users focus away from a form. Depending on your flow, you might be discarding this HTML all together.

  1. Alternatively, if the only time information will be hidden from a user if when a window is closed or the user navigates to a different page, instead of #2 you can use the even simpler:

    $(window).bind('beforeunload', function() {     if (window.formDirty) {       return 'You have unsaved changes. Navigating away will lose these! Continue?'     }   } 

but this approach means that you’ll have to unset formDirty on submit as well with something like:

   $('form submit').click( function() {      window.formDirty = false;      return true;   } 

Pretty easy! This is simple enough and improves the user experience enough that it might be worth including in your template for new projects.

What’s on your list of ‘must-have’ things to include on every project? (Other than tests of course!)

Not Happy with Your Current App, or Digital Product?

Submit your event

Let's Discuss Your Project

Let's Discuss Your Project