1

If I am making any change in the page and then attempting to navigate away without saving, I want an error message to ask if we want to save our changes.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Nitish
  • 834
  • 4
  • 15
  • 26
  • This might help. Check this: http://stackoverflow.com/questions/1235024/asp-net-jquery-dirty-forms-and-window-onbeforeunload – TRR Apr 24 '12 at 06:18
  • @rutwick—it may be better than nothing, but rather than put a click listener on every form control as suggested there, much better to have one *beforeunload* listener and test the current *value* of form controls vs their *defaultValue*, and remove the listener when the form submits so it isn't called when not necessary. – RobG Apr 24 '12 at 06:38

2 Answers2

1

onbeforeunload event is what you need. Bind a function to it which returns a string to be displayed (for Chrome only, other browsers will show default message) whenever user tries to navigate away (pressing back, forward, clicking on a link, closing the tab or window itself) from the page.

A confirm like dialog is presented to the user, if user chooses to proceed, the action that he requested is executed. If he chooses to stay on the page nothing happens.

$('input').change(function(){
    window.onbeforeunload = function(){
         //Return the message that should be displayed in Chrome.
         // Other browsers will show default message.
         return "You have unsaved changes on this page";
     };
});

When the changes are saved simply set window.onbeforeunload = null to remove the message when user tries to navigate away from the page.

Juzer Ali
  • 4,109
  • 3
  • 35
  • 62
0

There a few things to consider.

What elements do you use for input. This will affect your elementSelector (used in the code below) If you use plugins such as jeditable you have to know more than the elements you use for input. You'll need to know the elements used to display the values as well.

if you bind to change, as in sudhirs answer, I suggest doing this with live instead of bind that way you automagically support inplace editing.

The flag solution where you set a flag on the change event does not cover the case where the user changes the value back to the original.

The idea of the code below is to iterate all the elements you want to monitor and store the original value. Befor unloading the values are then compared an if a change is found a warning should be given.

$(function(){
   function getVal(){
      var val,node = $(this),nodeType = node.attr('type');
       if(this.nodeName.toLowerCase() == input){
           if(nodeType === "checkbox" || nodeType === "radio"){
               val = node.attr('checked');
           } else{
               val = node.val();
           }
       } else{
          val = node.text();
       }
       return val;
   }
   $(elementSelector).each(function)({
       $(this).data('original',getVal.Call(this));
   });
   window.onbeforeunload = function(){
      var hasChanges;
      $(elementSelector).each(function(){
            var org = $(this).data('original'),val = getVal.call(this);
            hasChanges = hasChanges || (org !== val)
      });
      if(hasChanges){
          return "Are you sure you wish to leave this page. Changes will be lost");
      }
   };
});

if the user stays on the page after saving (Ie. the data is posted to the server using ajax) you will need to update the store values so that subsequent changes correctly trickers the message again but no message is trickered if the user does not change anything after saving

Rune FS
  • 21,497
  • 7
  • 62
  • 96