Mark
Mark

Reputation: 647

Using jquery to monitor form field changes

Trying to learn some jquery to implement an autosave feature and need some assistance. I have some code to monitor the status of form fields to see if there has been any change. Everything works, but I need to only monitor the changes in a specific form, not all form inputs on the page. There is a search box and a newsletter form on the same page and when these form fields are changed, they are detected as well, which I need to filter out somehow or better yet, only target the specific form.

$(function(){
    setInterval("CheckDirty()",10000);
    $(':input').each(function() {
        $(this).data('formValues', $(this).val());
    });
});

function CheckDirty()
{
    var isDirty = false;

    $(':input').each(function () {
        if($(this).data('formValues') != $(this).val()) {
            isDirty = true;
        }
    });

    if(isDirty == true){
        alert("isDirty=" + isDirty);
    }
}

Upvotes: 13

Views: 36740

Answers (8)

Codeparl
Codeparl

Reputation: 326

I respect all the working answers but for me I think using the focus event might be much better than change event. This is how I accomplished my watchChange() function is JS:

 var changeInterval = 0;
 var changeLength = 0; //the length of the serverData
 var serverData = {value:''}; //holds the data from the server
 var fieldLength = 0; //the length of the value of the field we are tracking
 var frequency = 10000;

  function watchChange() {
    $input.on('focus', function() {
    var $thisInput = $(this);

    //we need the interval value so that we destroy
    //setInterval when the input loses focus.
    changeInterval = setInterval(function() {

        changeLength = serverData.value.length;
        fieldLength = $thisInput.val().length;

        //we only save changes if there is any modification
        if (changeLength !== fieldLength) {
            $.ajax({
                url: 'path/to/data/handler',
                dataType: 'json',
                data: "data=" + $thisInput.val(),
                method: 'post'
            }).done(function(data) {
                serverData = data;
            }); //end done
        } //end if

    }, frequency); //end setInterval

    //and here we destroy our watcher on the input
    //when it loses focus
}).on('blur', function() {
    clearInterval(changeInterval);
});

}

Even though this approach seems to be naive but it gave me what I wanted!

Upvotes: 0

user4772709
user4772709

Reputation:

var $jq= jQuery.noConflict();
         $jq(function() {                       $jq('#extensibleForm').data('serialize',$jq('#extensibleForm').serialize());
 });


function formHasChanged(){
      if($jq('#extensibleForm').serialize()!=$jq('#extensibleForm').data('serialize')){
              alert("Data Changed....");
              return (false);
}
return true;
}

Upvotes: 2

Diego
Diego

Reputation: 16714

Here you can see it working: http://jsfiddle.net/paska/zNE2C/

$(function(){
    setInterval(function() {
        $("#myForm").checkDirty();
    },10000);
    $("#myForm :input").each(function() {
        $(this).data('formValues', $(this).val());
    });

    $.fn.checkDirty = function() {
        var isDirty = false;

        $(this).find(':input').each(function () {
            if($(this).data('formValues') != $(this).val()) {
                isDirty = true;
            }
        });

        if(isDirty == true){
            alert("isDirty=" + isDirty);
        }
    };
});

Upvotes: 1

wdm
wdm

Reputation: 7189

You can use the .change() function and then use $(this) to denote you want to work with just the field that is actively being changed.

$('#myForm input[type="text"]').change(function() {

    $(this)...

});

Edit: #myForm is your form ID so you can target a specific form. You can even specify just type="text" fields within that form, as in my example.

Upvotes: 1

naiquevin
naiquevin

Reputation: 7796

You can specify an id attribute (say theForm) to your form element and then select only those input fields inside it.

then try selecting with

$(':input', '#theForm')

Upvotes: 0

David Magalhães
David Magalhães

Reputation: 822

I think you can use a class to select the type of input you want.

<input class="savethis" ... />

Then in jQuery use this.

$(':input .savethis').each(function() { ...

Upvotes: 0

JohnP
JohnP

Reputation: 50019

Just add a class to the form and use it to filter

$('.form :input').each(function() {
    $(this).data('formValues', $(this).val());
});

EDIT

Just a suggestion, you can attach the change event directly to the form

live demo here : http://jsfiddle.net/jomanlk/kNx8p/1/

<form>
    <p><input type='text'></p>
    <p><input type='text'></p>
    <p><input type='checkbox'></p>
</form>

<p><input type='text'></p>

<div id='log'></div>

$('form :input').change(function(){
   $('#log').prepend('<p>Form changed</p>')
});

You can easily improve this by adding a timer and making it save every xx seconds.

Upvotes: 28

Patricia
Patricia

Reputation: 7802

what's your form's id?

you just need to make your selector more specific :)

instead of $(':input').each(function() {

use

$('#yourFormId').find(':input').each(function() {

Upvotes: 1

Related Questions