29

I want to know if a form has changed at all. The form can contain any form element, such as input, select, textarea etc. Basically I want a way to display to the user that they have unsaved changed made to a form.

How can I do this using jQuery?

To clarify: I want to catch ANY change to the form, not only to input elements but to all other form elements as well, textarea, select etc.

5
  • When do you want to show/check that? Commented Nov 7, 2014 at 8:01
  • @dfsq , if form modified ,and user clicks on CLOSE tab or goes to other page ,to alert him,that PLz save changes you made. Commented Nov 7, 2014 at 8:06
  • 1
    Please refer the following post stackoverflow.com/questions/3025396/jquery-form-change Commented Nov 7, 2014 at 8:09
  • Refer the following post stackoverflow.com/questions/3025396/jquery-form-change Commented Nov 7, 2014 at 8:13
  • Please stop spamming Commented Nov 7, 2014 at 8:16

1 Answer 1

85

The approach I usually take in such a case is that I check serialized form value. So the idea is that you calculate initial form state with $.fn.serialize method. Then when needed you just compare current state with the original serialized string.

To target all input elements (select, textarea, checkbox, input-text, etc.) within a form you can use pseudo selector :input.

For example:

var $form = $('form'),
    origForm = $form.serialize();

$('form :input').on('change input', function() {
    $('.change-message').toggle($form.serialize() !== origForm);
});
.change-message {
    display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
    <div class="change-message">You have unsaved changes.</div>
    <div>
        <textarea name="description" cols="30" rows="3"></textarea>
    </div>
    <div>Username: <input type="text" name="username" /></div>
     <div>
        Type: 
        <select name="type">
            <option value="1">Option 1</option>
            <option value="2" selected>Option 2</option>
            <option value="3">Option 3</option>
        </select>
    </div>
    <div>
        Status: <input type="checkbox" name="status" value="1" /> 1
        <input type="checkbox" name="status" value="2" /> 2
    </div>
</form>

Sign up to request clarification or add additional context in comments.

5 Comments

Great answer. Quesiton though, why doesn't this work without serializing? I mean, is there a way to do this without serializing?
Well you need a way to compare all form element values. I just found that serialization is very convenient way to do that. It's only one line of code. And this string only depends on input values, exactly what we need. It also properly work when user reverts changes. Serialized string also reverts to its original value.
This is a great solution! A better solution than here: stackoverflow.com/questions/3025396/… where they use data attribute, because solution like that is a one-way, once input changed, form will always stated as changed, while, this solution is two-way. If user input then deleting what he input, the form will not stated as changed because the serialize is matched. :) Doesn't it?
This works great! I had one issue where I had a tool that generated a random password and plopped it into the password fields, and that didn't register as a change... so I had to call .change() on those password fields after I updated their value (or you could call .trigger('change')), and it works great!
Great simple solution. Top Answer!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.