AngularJS check if form is valid in controller
Categories:
Mastering AngularJS Form Validation in Your Controller

Learn how to effectively check and manage the validity of AngularJS forms directly within your controllers, ensuring robust user input and application logic.
AngularJS provides powerful mechanisms for form validation, making it easy to ensure user input meets specific criteria. While much of the validation can be handled declaratively in the HTML, there are often scenarios where you need to programmatically check the form's validity within your JavaScript controller. This article will guide you through the essential techniques for accessing form state, understanding validation properties, and reacting to form validity changes in your AngularJS applications.
Understanding AngularJS Form Objects
When you define a form in AngularJS using the <form>
tag and give it a name
attribute, AngularJS automatically creates a form controller object and exposes it on the scope. This object contains a wealth of information about the form's state, including its validity. Each input field within the form that has an ng-model
and a name
attribute also gets its own controller object, nested under the form controller.
flowchart TD A[HTML Form <form name="myForm">] --> B{Form Controller Object ($scope.myForm)} B --> C[Input Field 1 <input name="myInput1">] B --> D[Input Field 2 <input name="myInput2">] C --> C1{Input Controller Object ($scope.myForm.myInput1)} D --> D1{Input Controller Object ($scope.myForm.myInput2)} C1 --> C2["$valid", "$invalid", "$dirty", "$pristine", "$touched", "$untouched"] D1 --> D2["$valid", "$invalid", "$dirty", "$pristine", "$touched", "$untouched"] B --> B1["$valid", "$invalid", "$dirty", "$pristine", "$submitted"] B1 --"Aggregates"--> C2 B1 --"Aggregates"--> D2
Structure of AngularJS Form and Input Controller Objects
The form controller object (e.g., $scope.myForm
) and individual input controller objects (e.g., $scope.myForm.myInput
) expose several useful properties that reflect their current state:
$valid
: Boolean, true if the form/input is valid.$invalid
: Boolean, true if the form/input is invalid.$pristine
: Boolean, true if the form/input has not been interacted with by the user.$dirty
: Boolean, true if the form/input has been interacted with by the user.$touched
: Boolean, true if the form/input has been blurred.$untouched
: Boolean, true if the form/input has not been blurred.$submitted
: Boolean, true if the form has been submitted (only on the form controller).
These properties are crucial for conditionally enabling/disabling buttons, showing error messages, or preventing submission.
Checking Form Validity in the Controller
The most common scenario is to check if the entire form is valid before performing an action, such as submitting data to a server. You can access the form object directly from your controller's scope and inspect its $valid
property.
<form name="myForm" ng-submit="submitForm()">
<label>
Username:
<input type="text" name="username" ng-model="user.name" required minlength="3">
<span ng-show="myForm.username.$error.required && myForm.username.$dirty">Username is required.</span>
<span ng-show="myForm.username.$error.minlength && myForm.username.$dirty">Username must be at least 3 characters.</span>
</label>
<br>
<label>
Email:
<input type="email" name="email" ng-model="user.email" required>
<span ng-show="myForm.email.$error.required && myForm.email.$dirty">Email is required.</span>
<span ng-show="myForm.email.$error.email && myForm.email.$dirty">Invalid email format.</span>
</label>
<br>
<button type="submit" ng-disabled="myForm.$invalid">Submit</button>
</form>
HTML form with basic validation attributes
angular.module('myApp', [])
.controller('MyFormController', ['$scope', function($scope) {
$scope.user = {};
$scope.submitForm = function() {
// Check if the form is valid
if ($scope.myForm.$valid) {
console.log('Form is valid! Submitting data:', $scope.user);
// Perform submission logic here, e.g., send to API
alert('Form submitted successfully!');
} else {
console.log('Form is invalid. Please correct the errors.');
// Optionally, mark all fields as touched to show errors immediately
$scope.myForm.$setSubmitted(); // Marks form as submitted, can trigger error display
alert('Please correct the form errors.');
}
};
}]);
Controller logic to check form validity on submission
ng-disabled="myForm.$invalid"
is great for preventing submission of invalid forms, using $scope.myForm.$setSubmitted()
in your controller can be useful to force the display of all validation messages after a submission attempt, even for untouched fields.Reacting to Form State Changes
Sometimes, you might need to perform actions or update UI elements dynamically based on the form's validity, not just on submission. You can use $watch
to observe changes in the form's $valid
or $invalid
properties.
angular.module('myApp', [])
.controller('MyFormController', ['$scope', function($scope) {
$scope.user = {};
$scope.formStatusMessage = 'Please fill out the form.';
// Watch for changes in the form's validity
$scope.$watch('myForm.$valid', function(newVal) {
if (newVal) {
$scope.formStatusMessage = 'Form is valid and ready to submit!';
} else {
$scope.formStatusMessage = 'Form has errors. Please correct them.';
}
});
$scope.submitForm = function() {
if ($scope.myForm.$valid) {
console.log('Form is valid! Submitting data:', $scope.user);
alert('Form submitted successfully!');
} else {
console.log('Form is invalid. Please correct the errors.');
$scope.myForm.$setSubmitted();
alert('Please correct the form errors.');
}
};
}]);
Using $watch
to react to form validity changes
<form name="myForm" ng-submit="submitForm()">
<!-- ... form fields as before ... -->
<p>{{ formStatusMessage }}</p>
<button type="submit" ng-disabled="myForm.$invalid">Submit</button>
</form>
HTML displaying a dynamic status message based on form validity
$watch
is powerful, be mindful of its performance implications in very complex forms with many inputs, as it can trigger frequently. For simple validity checks on submission, direct access to $scope.myForm.$valid
is usually sufficient.