I’ll admit I’m fairly new to the movement that is AngularJS. The Javascript elements make it feel like a familiar old friend, but at times you go to implement a specific task only to hit a wall. And then another one and then another one. I’ve got a designer who is having a lot of fun with the responsiveness of the framework so I’ve had to get a little creative with my solutions. Specifically, he’s got two levels of validation. One that displays a message to the user as to what is wrong that most of us are used to seeing. The other is an icon that sits out to the right of the field telling you if what you are typing is valid or not in real time.
The validation message wasn’t a problem as I just nested two levels of ng-show tags to filter down to the correct message the user should be seeing.
Your email is required.
I’ll admit I tried this for the icons as well, resting these tags back-to-back, to no avail. Consistently, it would show the invalid icon without ever displaying the valid one. I stumbled across the $scope.$watch and it was immediately intriguing. I would pass in the test to see if the field had been interacted with (e.g. $dirty), and it made it in fine. I set the icon via an if – else evaluation, but it never reset as the user interacted with the form. I tried nesting the $scope.$watch statements, but Angular didn’t like my creative flair for code use.
Finally, I stumbled across the $scope.$watchGroup feature. It seems you could set it up to monitor multiple values at once which seemed to be exactly what I was looking for. I lined up each of the form field evaluation statements inside the array and called each back to evaluate them.
$scope.$watchGroup(['loginForm.email.$dirty','loginForm.password.$dirty','loginForm.email.$invalid','loginForm.password.$invalid'], function(newVal, oldVal){
// looks at the email field
if (newVal[0] && newVal[2])
$scope.userNameCheck = "error";
else if (newVal[0] && !newVal[2])
$scope.userNameCheck = "success";
else
$scope.userNameCheck = "";
// looks at the password field
if (newVal[1] && newVal[3])
$scope.passwordCheck = "error";
else if (newVal[1] && !newVal[3])
$scope.passwordCheck = "success";
else
$scope.passwordCheck = "";
});
I save it out only to get an error in the console informing me that $scope.$watchGroup is not a function. Say what? It seems this iteration was introduced in Angular 1.3 and I was referencing 1.2.16 for some unknown reason. I updated my versioning to the latest Angular release, and it all fell into place.
Originally, I just had it as an if – else statement with the evaluation statement only on the if. It had the problem of showing the valid check when the form was originally loaded (e.g. technically valid, but not dirty) so I added an extra else if to evaluate this successful condition so I could set the default condition to an empty string.
It provides a pretty nice effect that definitely adds something to the validation all the while keeping the designer happy.
0 Comments on "Using $scope.$watchGroup to Monitor Form Fields for Validation in AngularJS"