1

I have a field in form which is to be validated depending upon the value of some other field. To achieve that I have created a validation directive.

More specifically I have a group of two radio buttons and a text field, which is to be validated, against the chosen radio button.

If first radio button is chosen, text-fields value can be 0-100 If second radio button is chosen, text-fields value can be 0-infinite

I pass the value of chosen radio-button to directive and depending upon that condition is checked for validation of text field's value.

So far so good. Things work fine for the scenario except for some edge cases.

For example if initially second radio button is chosen, then if you write 400 in text field and then choose first radio button. It doesn't show invalid field.

directive('discountValidator', function () {
return {
  require: 'ngModel',
  scope: {
    discountValidator: '='
  },
  link: function (scope, attr, elem, ngModel) {
    ngModel.$validators.discount = function (modelvalue) {
      return scope.discountValidator.toLowerCase() === 'flat' ? modelvalue >= 0 : (modelvalue >= 0 && modelvalue <= 100);
    };
  }
};

});

html

<md-input-container class="md-block">
      <md-radio-group ng-model="vm.type" layout>TYPE&nbsp;
        <md-radio-button value="PERCENT" checked>%</md-radio-button>
        <md-radio-button value="FLAT">Flat</md-radio-button>
      </md-radio-group>
    </md-input-container>

    <!-- Discount Amount Field-->
    <md-input-container class="md-block">
      <input type="number" name="discountAmt" ng-model="vm.value" required discount-validator="vm.type">

      <!-- Error Messages -->
      <div ng-messages="form1.discountAmt.$error" ng-if="form1.$submitted || form1.discountAmt.$touched">
        <div class="error" ng-message="required">Required</div>
        <div class="error" ng-message="discount">Invalid Discount</div> 
      </div>
    </md-input-container>

  </div>

function DiscountValidator() {
    return {
      require: 'ngModel',
      scope: {
        discountValidator: '='
      },
      link: function (scope, attr, elem, ngModel) {
        ngModel.$validators.discount = function (modelvalue) {
          return scope.discountValidator.toLowerCase() === 'flat' ? modelvalue >= 0 : (modelvalue >= 0 && modelvalue <= 100);
        };
      }
    };
  }

var app = angular.module('app', ['ngMessages', 'ngMaterial'])
      .controller('mainCtrl', function($scope){  
        var vm = this;
        vm.onSubmit = function(form) {

        };
        
        vm.type='PERCENT';
      })
    .directive('discountValidator', DiscountValidator);
<!DOCTYPE html>
<html ng-app='app'>
<head>
<meta name="description" content="Dynamic validation in AngularJs">
   <!-- Angular Material style sheet -->
  <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0-rc2/angular-material.min.css">
    
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>



<body ng-controller='mainCtrl as vm'>
  <md-content>
    <form name="form1" ng-submit="vm.onSubmit(addressForm)" novalidate>
      <div layout="column">

        <md-input-container class="md-block">
          <md-radio-group ng-model="vm.type" layout>TYPE&nbsp;
            <md-radio-button value="PERCENT" checked>%</md-radio-button>
            <md-radio-button value="FLAT">Flat</md-radio-button>
          </md-radio-group>
        </md-input-container>

        <!-- Discount Amount Field-->
        <md-input-container class="md-block">
          <input type="number" name="discountAmt" ng-model="vm.value" required discount-validator="vm.type">

          <!-- Error Messages -->
          <div ng-messages="form1.discountAmt.$error" ng-if="form1.$submitted || form1.discountAmt.$touched">
            <div class="error" ng-message="required">Required</div>
            <div class="error" ng-message="discount">Invalid Discount</div> 
          </div>
        </md-input-container>

      </div>

      <md-button type='submit' class='md-primary'>Submit</button>
    </form>
  </md-content>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-animate.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-aria.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-messages.min.js"></script>

  <!-- Angular Material Library -->
  <script src="https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0-rc2/angular-material.min.js"></script>

  
</body>
</html>

2
  • Probably the simplest solution for your example would be to clear the input field if the radio button is changed. Commented May 25, 2016 at 12:03
  • thanks @SeRu for lifesaving trick Commented May 25, 2016 at 14:59

1 Answer 1

1

Since my comment solved the problem I'll post it as answer. The simplest solution for the example would be to clear the input field if the radio button is changed.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.