2

In the example below, the value in input 'ia' can get out of sync with the model value (e.g. if you type in 'aaa'). What I would like to achieve is when the input 'ia' loses focus, update its value to the formatted value of the current model value (e.g. when model value is null, update the view value to string 'N/A'). Anybody know I this might be achieved? Thanks.

The current behaviour is if you type in 'aaa' as profession, model value is updated to null bot 'aaa' stays in the input.

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html ng-app="myapp">

<head>

  <script>
    var myapp = angular.module('myapp', []);
    myapp.controller('mycontroller', function($scope) {
      $scope.model = {
        name: "ttt",
        age: 24,
        profession: null
      };
    });

    var professionList = [{
      id: 1,
      name: "p1"
    }, {
      id: 2,
      name: "p2"
    }, {
      id: 3,
      name: "p3"
    }, {
      id: 4,
      name: "p4"
    }];

    myapp.directive("prof", function() {
      return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {

          ngModel.$formatters.push(function(value) {
            for (var i = 0; i < professionList.length; i++) {
              if (value == professionList[i].id)
                return professionList[i].name;
            }
            return "N/A";
          });

          //format text from the user (view to model)
          ngModel.$parsers.push(function(value) {
            for (var i = 0; i < professionList.length; i++) {
              if (value == professionList[i].name)
                return professionList[i].id;
            }
            return null;
          });

          element[0].ngModel = ngModel;
        }
      };
    });
  </script>
</head>

<body ng-controller="mycontroller">
  <form>
    Name:
    <input ng-model="model.name" />
    <br />Age:
    <input ng-model="model.age" />
    <br />Profession:
    <input prof="" ng-model="model.profession" id="ia" />
    <input ng-model="model.profession" />
  </form>

  <hr />Name: {{model.name}}
  <br />Age: {{model.age}}
  <br />Profession: {{model.profession}}



</body>

</html>

UPDATE: I found a solution based on the answer in this question

//add this to the link function:
ngModel.$render = function(){
    element[0].value = ngModel.$viewValue;
};

element[0].onblur = function(){
    var viewValue = ngModel.$modelValue;
    for (var i in ngModel.$formatters) {
        viewValue = ngModel.$formatters[i](viewValue);
    }
    ngModel.$viewValue = viewValue;
    ngModel.$render();
};
Community
  • 1
  • 1
zhy2002
  • 389
  • 5
  • 11

1 Answers1

0

While returning null you are not re-initializing ngModel and I dont think directive is needed here , there is something called ng-blur in angularjs,

Profession : <input ng-model="model.profession" ng-blur="checkProfession() "/>
Profession ID : <input ng-model="model.id" />

In your controller write a function as,

   $scope.checkProfession=function(){
     var flag=0;
     for (var i = 0; i < professionList.length; i++) {
        if ($scope.model.profession == professionList[i].name){
          $scope.model.id=professionList[i].id;
          flag=1;
        }
        if(!flag){
          $scope.model.id="";
          $scope.model.profession="";
        }
    }
  }