Select/submit only changed form fields with jQuery

Another option would be to mark the fields as disabled before they are submitted. By default disabled fields will not be serialized or submitted with a default form post.

Simple example:

function MarkAsChanged(){
    $(this).addClass("changed");
}
$(":input").blur(MarkAsChanged).change(MarkAsChanged);

$("input[type=button]").click(function(){
    $(":input:not(.changed)").attr("disabled", "disabled");
    $("h1").text($("#test").serialize());
});

on jsfiddle.


Another approach would be to serialize the form when the page loads, and then on submit, only submit the changes.

$(function() {

  var $form = $('form');

  var startItems = convertSerializedArrayToHash($form.serializeArray()); 

  $('form').submit() {
    var currentItems = convertSerializedArrayToHash($form.serializeArray());
    var itemsToSubmit = hashDiff( startItems, currentItems);

    $.post($form.attr('action'), itemsToSubmit, etc.
  }
});

Then, all you have to write is the hashDiff function, which is straightforward and generally useful.

This is nice because it can easily be packaged into a plugin, and it can work repeatedly on the same form if you're using Ajax.

function hashDiff(h1, h2) {
  var d = {};
  for (k in h2) {
    if (h1[k] !== h2[k]) d[k] = h2[k];
  }
  return d;
}

function convertSerializedArrayToHash(a) { 
  var r = {}; 
  for (var i = 0;i<a.length;i++) { 
    r[a[i].name] = a[i].value;
  }
  return r;
}

Here's a minimal test:

  describe('hashDiff()', function() {
    it('should return {} for empty hash',function() {
      expect(hashDiff({},{})).toEqual({});
    });
    it('should return {} for equivalent hashes',function() {
      expect(hashDiff({a:1,b:2,c:3},{a:1,b:2,c:3})).toEqual({});
    });
    it('should return {} for empty hash',function() {
      expect(hashDiff({a:1,b:2,c:3},{a:1,b:3,c:3})).toEqual({b:3});
    });
  });