ngChange-like functionality for the entire form

angularjs, forms, onchange

Solution

There isn't a built-in way to do `ng-change` for a form.

It may not even be needed, because if you organized your view model properly, then your form inputs are likely bound to a certain scope-exposed property:

$scope.formData = {};

and in the View:

<form name="form1">
  <input ng-model="formData.a">
  <input ng-model="formData.b">
</form>

Then you could deep-watch (with `$watch`) for model changes (and apply whatever debounce option on elements that you need):

$scope.$watch("formData", function(){
  console.log("something has changed");
}, true);

Then problem is, of course, that this is a deep-watch and it is expensive. Also, it reacts not only to changes in the Form, but also to a change in `formData` from any source.

So, as an alternative, you could create your own directive to compliment the form and react to form's change events.

.directive("formOnChange", function($parse){
  return {
    require: "form",
    link: function(scope, element, attrs){
       var cb = $parse(attrs.formOnChange);
       element.on("change", function(){
          cb(scope);
       });
    }
  }
});

and the usage is:

<form name="form1" form-on-change="doSomething()">
  <input ng-model="formData.a">
  <input ng-model="formData.b">
</form>

plunker for illustration.

Note, that the "change" event is fired only on blur for a text input, as per jQuery documentation:

The `change` event is sent to an element when its value changes. This event is limited to `<input>` elements, `<textarea>` boxes and `<select>` elements. For select boxes, checkboxes, and radio buttons, the event is fired immediately when the user makes a selection with the mouse, but for the other element types the event is deferred until the element loses focus.

Problem

I would like to do an equivalent of `ng-change` for the entire form whenever there is a change in one of its input fields. I know that since AngularJS 1.3 I have the debounce option but it applies only for a single input. I'm looking for a "debounce"/"on change" functionality that will apply for the entire form.

Original source