John Magnolia
John Magnolia

Reputation: 16793

How to test if users has made any changes to a form if they haven't saved it

Basically the same functionality as stackoverflow when posting a question, if you start writing a post then try to reload the page. You get a javascript alert box warning message.

I understand how to check if the form has been changed, although how do I do the next step.

I.E: How to I check this when leaving the page, on here you get "This page is asking you to confirm that you want to leave - data you have entered may not be saved."?

EDIT: found correct answer here to another question https://stackoverflow.com/a/2366024/560287

Upvotes: 1

Views: 2652

Answers (3)

RobG
RobG

Reputation: 147363

There are a number of ways to check if any of a form's controls have changed.

To check for changes from the default, most can be checked against the defaultValue property. For radio buttons, you should always have one checked by default, so check if it's still selected or not. Similarly for selects, set the selected attribute for the default option and see if it's still selected, and so on.

Alternatively, if all your form controls have an ID or unique name, you can collect all their values onload and then check their values when the form is submitted.

Another method is to listen for change events on each form control, but that is a bit over the top.

Here's a POJS version that takes the same approach as rkw's answer:

  /*
     Check if any control in a form has changed from its default value.

     Checks against the default value for inputs and textareas,
     defaultChecked for radio buttons and checkboxes, and 
     default selected for select (option) elements.

  */
  function formChanged(form) {
    var control, controls = form.elements;
    var tagName, type;

    for (var i=0, iLen=controls.length; i<iLen; i++) {
      control = controls[i];
      tagName = control.tagName.toLowerCase();
      type = control.type;

      // textarea
      if (tagName == 'textarea') {
        if (control.value != control.defaultValue) {
          return true;
        }

      // input
      } else if (tagName == 'input') {

        // text
        if (type == 'text') {
          if (control.value != control.defaultValue) {
            return true;
          }

        // radio and checkbox
        } else if (type == 'radio' || type == 'checkbox') {
          if (control.checked != control.defaultChecked) {
            return true;
          }
        }

      // select multiple and single
      } else if (tagName == 'select') {
        var option, options = control.options;

        for (var j=0, jLen=options.length; j<jLen; j++) {
          option = options[j];
          if (option.selected != option.defaultSelected) {
            return true;
          }
        }
      }
    }
    // Not really needed, but some like the return value to 
    // be a consistent Type
    return false;
  }

Note that you need to be careful with select elements. For a single select, you should always set one option to selected, as if there is no default selected, some browsers will make the first option selected and others wont.

Upvotes: 0

rkw
rkw

Reputation: 7297

I'm very sure that if you search, 'jQuery detect form change plugin', you will find something much more usable than this semi-pseudo code i'm about to write:

formChanged = function(form) {
    form.find('input[type="text"], textarea').each(function(elem) {
        if (elem.defaultValue != elem.value) {
            return true;
        }
    });
    // repeat for checkbox/radio: .defaultChecked
    // repeat for ddl/listbox: .defaultSelected
    return false;
}

usage:

if (formChanged($('form')) { // do something }

Note that this is to detect changes against the original rendered value. For instance, if a textbox has a value = "x", and the user changes it to "y", then changes it back to "x"; this will detect it as NO change.

If you do not care about this scenario, you can just do this:

window.formChanged = false;

$(':input').change(function() {
    window.formChanged = true;
});

Then you can just check that value.

Upvotes: 4

Bojangles
Bojangles

Reputation: 101473

Yes, it is JavaScript as HTML is just a markup language.

Yes, jQuery can be used for this. It's preferable over vanilla JavaScript as it makes things easier, although it does add some overhead.

Upvotes: 1

Related Questions