Blog

Some of my recent posts and ramblings.

Form Savior – a jQuery plugin to prompt save of unsaved changes in form

I was tasked to find a way to prevent accidental loss of information if the user navigated away from the page after changing the form. This article from 4GuysFromRolla helped me get started on the solution. But it required a lot of effort from the developer to implement for each form. I think I came up with a more easier way to implement the functionality. Packaged it into a jQuery plugin, it’s called Form Savior. It has a simple purpose, if any inputs are changed, it will prompt if the user is navigating away without saving them.

How it Works

Here is the sourcecode:

(function ($, window, document) {
    "use strict";
    $.fn.formSavior = function (options) {
        return this.each(function () {

            var cfg = {
                'msg'   : 'There are unsaved changes on this form',
                'noprompt' : 'fs_noprompt'
            };

            if (options) {
                $.extend(cfg, options);
            }
            var originals = '',
                showalert = true,
                $form = $(this),
                $win = $(window),
                $doc = $(document);

            // Adding a click listener for noprompt links, onclick adds a noprompt class to the form
            $doc.on('click', '.' + cfg.noprompt, function () {
                $(this).closest("form").addClass(cfg.noprompt);
            });

            // When multiple forms are on the page, and one of the forms triggers the beforeunload 
            // alert, reset showalert back to true 
            $win.bind('fs_beforeUnloadTriggered', function () {
                showalert = true;
            });

            function extractFormData() {
                var formdata = $form.serialize();
                $form.find('input[type=file]').each(function () {
                    formdata = formdata + $(this).val();
                });
                return formdata;
            }

            function saveOriginals() {
                originals = extractFormData();
            }

            function allowSave() {
                showalert = false;
            }

            function savePrompt() {
                var current = extractFormData();
                if (current !== originals &&
                        showalert === true &&
                        !$form.hasClass(cfg.noprompt)) {
                    $win.trigger('fs_beforeUnloadTriggered');
                    return cfg.msg;                 // The beforeunload event takes 
                                                        // only a string as argument and displays the prompt.
                }
            }
            $doc.ready(saveOriginals);              // Saving original state of the form once the document is loaded
            $form.submit(allowSave);                // Allowing form to save when it is submitted
            $win.bind('beforeunload', savePrompt);  // Function call here to check if the form has changed
        });

    };

})(jQuery, window, document);

Calling the function

    $(document).ready(function() {
	$("#personInfo").formSavior();
    }); // Optionally, you can set a parameter, msg, which is the message you want to show to the user.

It uses the serialize method in jQuery and the onbeforeunload event of the browser.

On Document Ready, saveOriginals() serializes the current inputs of the form and saves them. When the user is navigating away(clicking on a link, refreshing page, closing window, etc), the plugin is triggered by the onbeforeunload event of the browser window and it checks if the form inputs have changed and alerts the user.

If the user is submitting the form, a flag ‘showalert’ is set to false, so that the message does not appear and the form is allowed to submit.

UPDATE: Added a couple of features, if a form has ‘fs_noprompt’ class, it will not show an alert. This is a way to allow leaving a page without showing the alert like a ‘Leave without saving’ link. Added support to check for file input changes as well.

Download From Github


9 comments.

  1. Go Irish!

    Great plug-in! Thanks for sharing.


  2. admin

    Thanks. Glad you found it useful.


  3. Taka

    I get an error Microsoft JScript runtime error: Object doesn’t support property or method ‘formSavior’…


  4. admin

    Please make sure you have included jquery and the form-savior javascript files. This example file on github should help! https://github.com/ianand2/Form-Savior/blob/master/index.html


  5. prashant

    hi,

    thanks for this plugin.
    i was seeing ur code on github. can u pls make me understand below code in your plugin.

    // Adding a click listener for noprompt links, onclick adds a noprompt class to the form
    $(‘.’+cfg.noprompt).live(‘click’, function() {
    $(this).closest(“form”).addClass(cfg.noprompt);
    });

    are you assigning a class to passed in forms? and you are not prompting for forms with these classes?


  6. admin

    Sorry for the late reply, Prashant, but yes, adding that class won’t show the prompt for that form. This is for cases where you do $(“form”).formSavior(), and you want to exclude some forms from doing the check.


  7. Martin

    Nice article , and sets of article from rolla. The code works , and the github integration is spot on, THanks,


  8. Jeff

    If I’m using a button that is outside of the tags to submit my form using onClick=”form_name.submit( );”, can I still get formSavior to allow the form to save without the prompt?


  9. Anand

    Yep, that should work!


Leave a Reply

Your email is never published nor shared. Required fields are marked *

You may use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>