Sample HTML
This HTML includes two forms to demonstrate that the JavaScript solution (below) won't cause change conflicts across forms.
<form>
<input name="foo" class="trackChanges" />
<input name="bar" class="trackChanges" />
<input name="bof" />
<input type="submit" />
</form>
<form>
<input name="foo" class="trackChanges" />
<input name="bar" class="trackChanges" />
<input name="bof" />
<input type="submit" />
</form>
The JavaScript (using jQuery)
$(".trackChanges").on("change", function(event) {
var input = $(this),
form = input.parents("form"),
data = form.data("changes") || {};
// log new change
data[input.attr('name')] = input.val();
// save changes
form.data("changes", data);
});
$("form").on("submit", function(event) {
var data = $(this).data("changes") || {};
console.log(data);
// just output the changes for now
event.preventDefault();
});
jsfiddle demo
I thinks this is a better solution because it bind the changes to each form using jQuery.data and then you can recall that information at any time.
This means you don't have to do any sort of change tracking with a form's ID
Trying to lead by example here, so I'm going to address this:
I assume this has something to do with the need to use some sort of push ch.push(key->value)
The problem with your code above doesn't have anything to do with [].push. The most glaring mistake of your code is that each time the onchange event gets fired, you're running this bit of code
ch[id] = {};
This essentially nukes the previous change that have been saved.