Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Watch form model for changes

Assuming a given form such as <form name="myForm">, it's easy enough to watch for validity, error, dirty state, etc. using a simple watch:

$scope.$watch('myForm.$valid', function() {
  console.log('form is valid? ', $scope.myForm.$valid); 
});

However, there doesn't appear to be an easy way to watch if any given input in this form has changed. Deep watching like so, does not work:

$scope.$watch('myForm', function() {
  console.log('an input has changed'); //this will never fire
}, true);

$watchCollection only goes one level deep, which means I would have to create a new watch for every input. Not ideal.

What is an elegant way to watch a form for changes on any input without having to resort to multiple watches, or placing ng-change on each input?

like image 463
Duncan Avatar asked May 06 '15 15:05

Duncan


2 Answers

Concerning the possible duplicate and your comment:

The directive solution in that question works, but it's not what I had in mind (i.e. not elegant, since it requires blur in order to work).

It works if you add true as third parameter for your $watch:

$scope.$watch('myFormdata', function() {
    console.log('form model has been changed');
}, true);

Further information see the docs.

Working Fiddle (check console log)


Another more angular way would be to use angular's $pristine. This boolean property will be set to false once you manipulate the form model:

Fiddle

like image 198
DonJuwe Avatar answered Oct 19 '22 19:10

DonJuwe


Based on my experience with my forms (new dev, but working with Angular for a while now), the elegant way to watch a form for changes is actually not to use any type of watch statement at all actually.
Use the built-in Angular boolean $pristine or $dirty and those values will change automatically on any input field or checkbox.
The catch is: it will not change the value if you add or splice from an array which had me stumped for a while.
The best fix for me was to manually do $scope.MyForm.$setDirty(); whenever I was adding or removing from my different arrays. Worked like a charm!

like image 21
leviathon Avatar answered Oct 19 '22 19:10

leviathon