Dismiss
Announcing Stack Overflow Documentation

We started with Q&A. Technical documentation is next, and we need your help.

Whether you're a beginner or an experienced developer, you can contribute.

Sign up and start helping → Learn more about Documentation →

I am trying to do validation on a input based on value selected from a dropdown.

JSFiddle: https://jsfiddle.net/Raj_13290/qqLnqw3f/9/

I am changing the value of ng-pattern in ng-change of dropdown. Validation works fine but when I change dropdown value previously entered values in input is not validating.

For example, If I select currency in dropdown and enter a text 'abc' so it validates but when I change dropdown to text it still show invalid value.

I have tried with higher version of Angular it works fine but for 1.2.23 it doesn't work.

Any solution is appreciated. thanks

share|improve this question
    
May I know, why you wanted to stay with older version 1.2.23, as newer version has not any problem? – Pankaj Parkar Mar 24 at 9:35
    
This is some legacy application which have some dependency of older version @PankajParkar – Manish Mar 24 at 9:37
up vote 1 down vote accepted

It seems that this is a bug angular.

I found a solution, but it is not very good.

Live example on jsfiddle.

var myApp = angular.module('myApp', []);

myApp.controller("MyCtrl", function($scope) {
  var tThis = this;
  $scope.dataTypeList = [{
    'id': 1,
    "label": "Currency"
  }, {
    'id': 2,
    "label": "Number"
  }, {
    'id': 3,
    "label": "Text"
  }];
  $scope.dataTypeValue;
  $scope.textValue = {
    text: ""
  };
  $scope.customPattern = /.*/;
  $scope.getCustomPattern = function(pInput) {
    if (!$scope.dataTypeValue)
      return $scope.customPattern;
    var dataTypeId = $scope.dataTypeValue.id;
    if (dataTypeId === 1) {
      $scope.customPattern = /^\d{1,10}$/;
    } else if (dataTypeId === 2) {
      $scope.customPattern = /^\d+$/;
    } else if (dataTypeId === 3) {
      $scope.customPattern = /^.*$/;
    }
    if (!$scope.getCustomPattern.isParser) {
      $scope.getCustomPattern.isParser = true;
      pInput.$setViewValue(pInput.$viewValue);
    } else {
      $scope.getCustomPattern.isParser = false;
    }
    return $scope.customPattern;
  };
});
input.ng-invalid {
  border-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
  <div ng-controller="MyCtrl">
    <ng-form name="MyForm">

      <h3>
     With dynamic pattern
    </h3>
      <select ng-model="dataTypeValue" ng-options="t as t.label for t in dataTypeList" ng-change="getCustomPattern(MyForm.input)">

      </select>

      <input type="text" ng-model="textValue.text" ng-pattern="getCustomPattern(MyForm.input)" ng-model-options="{allowInvalid:true}" name="input">
      <br>
      <br>
      <br>Data type: {{dataTypeValue}}
      <br>Entered value: {{textValue}}

    </ng-form>
  </div>
</div>

share|improve this answer
    
Thanks Stepan, good work!!! It worked. The local variable 'isParser' was not required. – Manish Mar 24 at 18:52
    
@Manish without local variable isParser i have recursive execution of function getCustomPattern. See this jsfiddle. – Stepan Kasyanenko Mar 25 at 4:11
    
This doesn't work without isParser check. I was referring var isParser = false line. – Manish Mar 25 at 11:41
    
I remove line of var = isParser. It should work. – Stepan Kasyanenko Mar 25 at 11:59
    
Thanks It works!!! – Manish Mar 25 at 12:24

From looking your problem it loks like not updating your CSS class based on the ng-pattern. Not gone into detail but this plunkr might help you.

https://plnkr.co/edit/JSgH3LZHQysIO71u03yF?p=preview

var myApp = angular.module('myApp', []);
myApp.controller("MyCtrl", function ($scope) {
var tThis = this;
$scope.dataTypeList = [{
        'id' : 1,
        "label" : "Currency"
    }, {
        'id' : 2,
        "label" : "Number"
    }, {
        'id' : 3,
        "label" : "Text"
    }
];
$scope.dataTypeValue;
$scope.textValue
$scope.customPattern = '';
$scope.className = "ng-invalid ng-invalid-pattern"
    $scope.setCustomPattern = function () {
    var dataTypeId = $scope.dataTypeValue.id;
    console.log(dataTypeId + 'llsdkfalskdf');
    if (dataTypeId === 1) {
        $scope.customPattern = /^\d{1,10}$/;
    } else if (dataTypeId === 2) {
        $scope.customPattern = /^\d+$/;
    } else if (dataTypeId === 3) {
        $scope.customPattern = /^.*$/;
    }
    return $scope.customPattern
};
$scope.$watch("[dataTypeValue, textValue]", function (nw, old) {
    var s = $('input[name=input]').val()
        $scope.textValue = s;
    var pattern = $scope.setCustomPattern()
        if (pattern.test($scope.textValue)) {
            $scope.className = "ng-valid ng-valid-pattern"
        } else {
            $scope.className = "ng-invalid ng-invalid-pattern"
        }
});

});
share|improve this answer
    
thanks Arun, nice finding!! It is a good solution but I can't use $watch because I have many input fields. – Manish Mar 24 at 18:55

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.