News

My Stats

  • Posts - 21
  • Comments - 20
  • Trackbacks - 0

Twitter












Recent Comments


Recent Posts


Archives


Post Categories



The typical way to check for whether anything has changed in the view when you’re navigating away from a page is to bind a method to the change event of each input and to set a flag if this has happened. This flag is then checked when leaving the page and a notification is shown to the user if the flag is raised. This is all good but it does not take into account things like changing the order of inputs and changing values back to their original values. Also, creating dynamic elements makes this way of doing things a bit tricky because you have to add registering of the handlers to each method which adds new elements.

Just recently I had to implement this kind of checking. The implementation makes use of jQuery and has been tested with ASP.NET MVC but I don’t see any reason why it should not work with other platforms as well (at least with some minor changes). So without further ado, here’s the code.

/**
The variable contains all the values of the new as found by the previous call 
to storeViewValues. */
var viewValues = []; /** Set this to true to enable dirty-checking for the current page. This is also set when registering change checking for the view. */ var enableDirtyCheck = false; /** Collects all view values and returns the array. */ function collectViewValues() { var newViewValues = []; // Store inputs. $('input:enabled').each(function () { if ($(this).attr('id') != null && $(this).attr('id') != '') { // Ignore the ones that have '.' in their IDs. These are not part
// of our input values, since they are not allowed by // MVC when generating inputs.
var id = $(this).attr('id'); if (id.indexOf('.') < 0) newViewValues.push({ selector: 'input', id: $(this).attr('id'),
value: $(
this).val() }); } }); // Store select values. $('select:enabled').each(function () { var that = this; if ($(this).attr('id') != null && $(this).attr('id') != '') { $(this).find('option:selected').each(function () { // Ignore the ones that have '.' in their IDs. These are not
// part of our input values, since they are not allowed by // MVC when generating inputs.
var id = $(that).attr('id'); if (id.indexOf('.') < 0) newViewValues.push({ selector: 'select', id:
$(that).attr(
'id'), value: $(this).val() }); }); } }); return newViewValues; } /** Stores the current view input and select values to viewValues. */ function storeViewValues() { viewValues = collectViewValues(); } /** Checks for changes in the view. You must call storeViewValues when the view is fully loaded before calling
this method. */
function checkChanges() { var hasChanged = false; if (enableDirtyCheck) { // Collect current input values. var newViewValues = collectViewValues(); if (newViewValues.length != viewValues.length) { hasChanged = true; } else { // Check values. for (var i = 0; i < newViewValues.length; i++) { var newViewValue = newViewValues[i]; var viewValue = viewValues[i]; if (newViewValue.id != viewValue.id) { hasChanged = true; break; } if (newViewValue.selector != viewValue.selector) { hasChanged = true; break; } if (newViewValue.value != viewValue.value) { hasChanged = true; break; } } } } if (hasChanged) return "The page contains modifications!"; return null; } /** Call this method at the end of the current view if you wish to enable dirty
checking for the view. */
function registerDirtyChecking() { $(document).ready(function () { // Default to checking whether the view is dirty or not. enableDirtyCheck = true; // Store existing values. storeViewValues(); window.onbeforeunload = function (e) { var ret = checkChanges(); if (ret != null) { e.returnValue = ret; return ret; } }; $('form').submit(function () { enableDirtyCheck = false; }); }); }

The implementation takes into account that Internet Explorer shows the message even when you return null from the onbeforeunload handler, which actually works on Chrome, for instance. I also added setting of enableDirtyCheck to false when submitting the form, to ignore the message when we’re actually submitting the changes.

To use the code, simply include the bit of code in your view and call registerDirtyChecking at the end of the view. This forces the document ready handler to be added as the last one to be called (if other document ready handlers don’t add new document ready handlers themselves, that is).


Comments

Gravatar # re: Checking if a view has changed in ASP.NET
Posted by triggerHappy on 1/10/2012 10:09 PM
Quick and dirty way of checking if user has changed values can be done something like this:

//-- js code --

var initialValues;

// doc ready
$(function() {
// get form initial values
initialValues = $('#formId').serialize();

window.onbeforeunload = function(e) {
var newValues = $('#formId').serialize();
if (initialValues !== newValues) {
// something has changed
}
};
}
Gravatar # re: Checking if a view has changed in ASP.NET
Posted by Napoleon on 11/26/2012 5:10 AM
/**
Call this method at the end of the current view if you wish to enable dirty
checking for the view.
*/

I'm not clearly about that yet. You can decribe it more clearly. Where I call that function. In aspx file or in code behind
Gravatar # re: Checking if a view has changed in ASP.NET
Posted by Timo Heinäpurola on 11/26/2012 10:33 PM
The function is a JavaScript function so you need to call it at the end of the ASPX-file.
Post A Comment
Title:
Name:
Email:
Comment:
Verification: