Javascript: Computing changed fields in forms

I’m building a new settings app for YouNow. In the app, users can modify their existing biographical information. This results in the need to identify which fields have been edited. There are a few ways to solve this.

Per-field events

One solution is to bind to a change event for each form element. For each fired event, you need to add that target to a list of changed fields. Luckily, a change event only occurs when textfields lose focus; otherwise, this could get unwieldy if it behaved like a keypress event. Checkboxes fire when clicked and selects fire when an option is clicked.

State Comparisons

I opted for an alternative implementation: an object to object comparison of fields. This formed the basis for a jquery plugin that I wrote called Form-Delta.

There are two objects in this implementation, the initial state and the delta state. The plugin allows you to dictate the initial state of the form by calling the $('form').formInitial() method – where the selector 'form' could be a class or id specific to your app.

This function iterates through all of the form elements and creates a key/value mapping of their name attributes and element values. Yes, this implementation depends heavily on the markup containing name attribute values for each form element. However, you’d do that for most form POST requests anyway.

The computation of the delta entails calling the $('form').formDelta() method. This captures of the current state of the form’s elements (similar to the formInitial() function and then does a bi-directional data comparison between the initial and delta states. The set difference is returned to the caller as an object.

Conclusion

This is awesome since you can now tell your backend only the fields that have changed – as opposed to sending all of the fields – creating unnecessary work for your backend.

The con of this implementation is that it’s creating a new delta object each time. This seems negligible since the info in my app’s form is unlikely to be changed often. You should probably consider calling formInitial() after a successful save response from the backend – since the form’s initial state is the saved state.

Hope it helps.