Conditional validations based on other fields

Loading

In AngularJS, conditional validations allow you to apply validation rules to a field based on the value of other fields in the form. This is useful in cases where a certain field should only be validated if another field has a specific value. For example, you might want to validate a “confirm password” field only if the “password” field has been filled in.

Implementing Conditional Validations in AngularJS

Conditional validations can be achieved by using AngularJS’s custom validators, which allow you to write your own validation logic based on the value of other fields.

Here’s a step-by-step guide to implementing conditional validations:

Example Scenario:

Let’s create a form where the “Confirm Password” field should only be validated if the “Password” field is not empty. Additionally, if the “Password” is filled, we will ensure that the “Confirm Password” matches the “Password”.

1. HTML Form Template

<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="FormController">
<form name="myForm" ng-submit="submitForm()" novalidate>
<label for="password">Password:</label>
<input type="password" name="password" ng-model="formData.password" ng-required="true" />

<br/><br/>

<label for="confirmPassword">Confirm Password:</label>
<input type="password" name="confirmPassword" ng-model="formData.confirmPassword"
ng-required="formData.password" ng-pattern="formData.password ? formData.password : ''" />

<span ng-show="myForm.confirmPassword.$error.required && myForm.confirmPassword.$dirty">Confirm Password is required.</span>
<span ng-show="myForm.confirmPassword.$error.pattern && myForm.confirmPassword.$dirty">Passwords must match.</span>

<br/><br/>

<button type="submit" ng-disabled="myForm.$invalid">Submit</button>
</form>
</body>
</html>

2. Controller Logic (app.js)

angular.module('myApp', [])
.controller('FormController', function($scope) {
$scope.formData = {}; // Holds form data

// Function to handle form submission
$scope.submitForm = function() {
if ($scope.myForm.$valid) {
alert("Form submitted successfully!");
} else {
alert("Please fill out the form correctly.");
}
};
});

Explanation:

  1. Password and Confirm Password Fields:
    • The Password field has a ng-required="true" directive, meaning it is required for the form to be valid.
    • The Confirm Password field has a conditional ng-required="formData.password". This means that the “Confirm Password” field is only required if the “Password” field has a value. If the “Password” is empty, the “Confirm Password” field will not be required.
  2. Custom Pattern Validation:
    • The Confirm Password field also has a ng-pattern directive. It uses the value of the Password field (formData.password) as a pattern. The ng-pattern ensures that the “Confirm Password” field will only match if the value of the “Confirm Password” field is the same as the “Password” field.
    • The pattern is conditional: if the “Password” field has a value, ng-pattern enforces that the “Confirm Password” matches the “Password”. If the “Password” field is empty, ng-pattern is essentially ignored, allowing any value in the “Confirm Password” field.
  3. Validation Messages:
    • There are two validation error messages:
      • One for the required validation (Confirm Password is required).
      • One for the pattern validation (Passwords must match).
  4. Submit Button Disable Logic:
    • The submit button is disabled with ng-disabled="myForm.$invalid". The button will remain disabled until the form is valid, ensuring that the user cannot submit the form with invalid data.

3. Explanation of Conditional Validation

Here’s the key part where we apply conditional validation based on other fields:

  • Conditional Required Field Validation (ng-required="formData.password"):
    • The ng-required directive is conditionally applied based on the value of the “Password” field. If “Password” is filled out, the “Confirm Password” becomes required. If “Password” is empty, the “Confirm Password” field is not required, and the form can be submitted without it.
  • Conditional Pattern Matching (ng-pattern="formData.password ? formData.password : ''"):
    • The ng-pattern directive checks if the value of the “Confirm Password” matches the “Password” field, but only if the “Password” is not empty. If the “Password” field is empty, the ng-pattern is essentially ignored, and any value can be entered into the “Confirm Password” field.

4. Custom Validator for Complex Conditional Validation

If your validation logic is more complex and cannot be easily handled with built-in directives, you can create custom validators. For example, you might want to apply a more complex rule to multiple fields.

Here’s how you can create a custom validator:

Custom Validator Example:

angular.module('myApp', [])
.controller('FormController', function($scope) {
$scope.formData = {}; // Holds form data

// Custom validator to check if the password and confirm password match
$scope.passwordMatch = function() {
if ($scope.formData.password && $scope.formData.confirmPassword) {
return $scope.formData.password === $scope.formData.confirmPassword;
}
return true; // Allow empty fields to pass
};

// Function to handle form submission
$scope.submitForm = function() {
if ($scope.myForm.$valid) {
alert("Form submitted successfully!");
} else {
alert("Please fill out the form correctly.");
}
};
});

HTML Template (with Custom Validator)

<input type="password" name="confirmPassword" ng-model="formData.confirmPassword" 
ng-required="formData.password" ng-class="{'error': !passwordMatch()}" />

In this example, the passwordMatch() function checks if the “Password” and “Confirm Password” fields match. If they don’t, it applies an error class to the “Confirm Password” field. This is just a basic example of a custom validator that can be used for more complex conditions.

Leave a Reply

Your email address will not be published. Required fields are marked *