0

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

2
  • May I know, why you wanted to stay with older version 1.2.23, as newer version has not any problem? Commented Mar 24, 2016 at 9:35
  • This is some legacy application which have some dependency of older version @PankajParkar Commented Mar 24, 2016 at 9:37

2 Answers 2

1

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>

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

3 Comments

Thanks Stepan, good work!!! It worked. The local variable 'isParser' was not required.
@Manish without local variable isParser i have recursive execution of function getCustomPattern. See this jsfiddle.
This doesn't work without isParser check. I was referring var isParser = false line.
1

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"
        }
});

});

1 Comment

thanks Arun, nice finding!! It is a good solution but I can't use $watch because I have many input fields.

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.