Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting/handling changed data in ASP.NET MVC / jQuery / JS

We need to universally handle changed data on forms in ASP.NET MVC. Our application has ~100 forms, and the user should be prompted if they start editing a form and click on anything other than Save (i.e. something like "Your data has been changed. Click OK to return to the form, or Cancel to lose all changes.").

It looks like SO implements this (while asking a question) using JavaScript. In general, is this the best way? Also, any tips on how best to implement this?

like image 614
Beep beep Avatar asked Jul 12 '09 15:07

Beep beep


2 Answers

The way I've done this is to use javascript to store the initial values of inputs when the page loads. Then I have a beforeunload handler that checks to see if any of the inputs have a different value than when the page was loaded. If any inputs are changed, it prompts the user to confirm that they want to leave the page, canceling the action if they cancel. In my submit logic, I set a flag that keeps the beforeunload check from happening so a submit doesn't get the prompt.

I suspect there is a jQuery plugin to do this, but I haven't implemented this since I started using jQuery. My earlier code used Prototype.

Edit: Couldn't find a jQuery plugin, but I could have just missed it. Here's a sample of how I might do it. Obviously, there's more that could be done. Note I wasn't able to get it to work with pure jQuery -- not sure exactly why, the popup would appear twice.

This should work with all input elements. You might want to change it to ignore/handle buttons, though. I only adjusted it to ignore a submit button (so it can post back without the popup). If other button types can cause a page unload, you may need to address that.

var CheckOnClose = function() {
    this.initialize();
}

CheckOnClose.prototype = {
    submitting: false,
    initialize: function() {
        var that = this;
        window.onbeforeunload = function() { return that.checkLeavePage(); }
    },
    isChanged: function() {
        var changed = false;
        $('input:not(:submit)').each( function() {
            var iv = $(this).data('initialValue');
            if ($(this).val() != iv) {
                changed = true;
                return false;
            }
        });
        return changed;
    },
    setSubmitting: function() {
        this.submitting = true;
    },
    checkLeavePage: function() {
        if (!this.submitting && this.isChanged()) {
            return 'You have some unsaved changes.';
        }
    }
}

var checker = new CheckOnClose();

$(document).ready(function() {

    $(':input:not(:submit)').each( function() {
        $(this).data('initialValue',$(this).val() );
    });
    $(':submit').click( function() {
        checker.setSubmitting();
    });
});
like image 62
tvanfosson Avatar answered Sep 28 '22 06:09

tvanfosson


JavaScript is your only shot for doing this. It doesn't even have to be a complicated bunch of code. All you have to do is have a global variable to flag if the form is in editing stages (var formEdited = false; would do), and then add this snippet to your page:

 window.onbeforeunload = confirmExit;
    function confirmExit()
    {
        if (formEdited)
        {
                return "You have attempted to leave this page.  If you have made any changes to the fields without Submitting the form, your changes will be lost.  Are you sure you want to exit this page?";
         }
          // no changes - return nothing      
    }
like image 34
synhershko Avatar answered Sep 28 '22 08:09

synhershko