Warning about unsaved form changes

I want to write jQuery code in the main file, so if there, if the user changes the page and there are any unsaved changes, the user should receive a warning. I got one answer from this: link

However, in most solutions I will have to write code on all pages. I want him to write in only one place, so that everyone does not need to worry to write it in their modules. My code is similar:

<script type="text/javascript"> var isChange; $(document).ready(function () { $("input[type='text']").change(function () { isChange = true; }) }); $(window).unload(function () { if (isChange) { alert('Handler for .unload() called.'); } }); </script> 

But every time I make changes to text fields, the change () event does not fire.

What could be wrong in the code?

EDIT: I changed .change () to .click and fired. I am using jquery 1.4.1 .. is it due to the jquery version that changes () does not work?

+55
javascript jquery
Aug 07 2018-12-12T00:
source share
7 answers

This is what I use, put all this code in a separate JS file and upload it to your header file so you don't have to copy this over and over again:

 var unsaved = false; $(":input").change(function(){ //triggers change in all input fields including text type unsaved = true; }); function unloadPage(){ if(unsaved){ return "You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?"; } } window.onbeforeunload = unloadPage; 

EDIT for $ not found:

This error can only be caused by one of three reasons:

  1. Your JavaScript file does not load correctly on your page
  2. You have a broken version of jQuery. This may be due to someone editing the main file or the plugin could overwrite the $ variable.
  3. You have JavaScript running until the page is fully loaded and jQuery is fully loaded.

Make sure all JS code is in this:

 $(document).ready(function () { //place above code here }); 

Change the save / send / send button exception

 $('#save').click(function() { unsaved = false; }); 

Edit to work with dynamic inputs

 // Another way to bind the event $(window).bind('beforeunload', function() { if(unsaved){ return "You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?"; } }); // Monitor dynamic inputs $(document).on('change', ':input', function(){ //triggers change in all input fields including text type unsaved = true; }); 

Add the above code to your alert_unsaved_changes.js file.

Hope this helps.

+90
Aug 07 2018-12-12T00:
source share

Version using form serialization:

Run this code when House is ready:

 // Store form state at page load var initial_form_state = $('#myform').serialize(); // Store form state after form submit $('#myform').submit(function(){ initial_form_state = $('#myform').serialize(); }); // Check form changes before leaving the page and warn user if needed $(window).bind('beforeunload', function(e) { var form_state = $('#myform').serialize(); if(initial_form_state != form_state){ var message = "You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?"; e.returnValue = message; // Cross-browser compatibility (src: MDN) return message; } }); 

If the user changes the field and then rolls back manually, a warning is not displayed

+10
Jan 20 '16 at 11:59
source share

the change event is triggered after the user is blurred from entering not for each character entered.

If you need it to be called every time something changes (even if the focus is still in this input field), you will have to rely on a combination of keys and a bunch of events to track inserts / cuts with the mouse only.

PS I hope you know that your approach to detecting changes is not the best? If the user enters any text, leaves the field, and then returns the changes, the script will warn him about the changed text.

+2
Aug 07 2018-12-12T00:
source share

You must register events not only for input, but also for text fields, if you mean textarea with a text field. You can use keyup for isChange so that you do not wait for the user to blur from this area.

 $("input[type='text'], textarea").keyup(function () { isChange = true; }) 
+2
Aug 07 2018-12-12T00:
source share

Why not just associate the event with the change callback?

 $(":input").change(function() { $(window).unbind('unload').bind('unload',function() { alert('unsaved changes on the page'); }); }); 

As an added bonus, you can use confirm and select the last element that triggered the change event:

 $(":input").change(function() { $(window).unbind('unload').bind('unload',(function(elem) {//elem holds reference to changed element return function(e) {//get the event object: e = e || window.event; if (confirm('unsaved changes on the page\nDo you wish to save them first?')) { elem.focus();//select element return false;//in jQuery this stops the event from completeing } } }($(this)));//passed elem here, I passed it as a jQ object, so elem.focus() works //pass it as <this>, then you'll have to do $(elem).focus(); or write pure JS }); 

If you have a save button, make sure that it unloads the unload event:

 $('#save').click(function() { $(window).unbind('unload'); //rest of your code here }); 
+1
Aug 07 2018-12-12T00:
source share

This is really a different version of @AlphaMale's answer, but improved in several ways:

 # Message displayed to user. Depending on browser and if it is a turbolink, # regular link or user-driven navigation this may or may not display. msg = "This page is asking you to confirm that you want to leave - data you have entered may not be saved." # Default state unsaved = false # Mark the page as having unsaved content $(document).on 'change', 'form[method=post]:not([data-remote]) :input', -> unsaved = true # A new page was loaded via Turbolinks, reset state $(document).on 'page:change', -> setTimeout (-> unsaved = false), 10 # The user submitted the form (to save) so no need to ask them. $(document).on 'submit', 'form[method=post]', -> unsaved = false return # Confirm with user if they try to go elsewhere $(window).bind 'beforeunload', -> return msg if unsaved # If page about to change via Turbolinks also confirm with user $(document).on 'page:before-change', (event) -> event.preventDefault() if unsaved && !confirm msg 

This is better in the following cases:

  • This is a coffee pot that IMHO automatically makes it better. :)
  • It is entirely based on event bubbles, so dynamic content is automatically processed (the @AlphaMale update also has this).
  • It works only with POST forms, because GET forms do not have data that we usually want to avoid losing (i.e. GET forms are usually search fields and filter criteria).
  • It is not necessary to bind to a specific button to save. At any time when the form is submitted, we assume that the submission is saved.
  • Turbolinks compatible. If you don't need to, just remove the two page: event bindings.
  • It is designed so that you can simply enable it along with the rest of your JS, and your entire site will be protected.
+1
Sep 16 '15 at 19:43
source share

I am using the function $('form').change , etc. to set a dirty bit variable. Not suitable for all changes (as in previous answers), but it catches everything that interests me in my application.

0
Oct 19 '16 at 8:15
source share



All Articles