1

I know that I can use formatters and parsers in my directive to transform my data like this:

  //format text going to user (model to view)
  ngModel.$formatters.push(function(value) {
    return value.toUpperCase();
  });

  //format text from the user (view to model)
  ngModel.$parsers.push(function(value) {
    return value.toLowerCase();
  });

Full example here http://plnkr.co/edit/i59xSdVPMxRkgERhj8RE?p=preview

But I can't get this to work when I am using a template inside my directive. My custom parser isn't called:

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

app.controller('MainCtrl', function($scope) {
  $scope.data = { name: ''};
});
app.directive('changecase', function () {
  return {
    restrict: 'E',
    require: 'ngModel',
    scope: { model: '=ngModel' },
    template: '<input type="text" ng-model="model"> {{ model }}',
    link: function (scope, element, attrs, ctrl) {

      //format text going to user (model to view)
      ctrl.$formatters.push(function(value) {
        return value.toUpperCase();
      });

      //format text from the user (view to model)
      ctrl.$parsers.push(function(value) {
        return value.toLowerCase();
      });
    }
  }
});

With this html:

  <body ng-controller="MainCtrl">
    <changecase ng-model="data.name"></changecase>
    <pre>model is: {{data.name}}</pre>
  </body>

I'm guessing that this is either a scope or timing issue, but I can't work it out. Can anyone see what I'm doing wrong?

Feel free to mess around with the Plunker here: http://plnkr.co/edit/FZ4UnW8wIhIwRV2jVvfB?p=preview

1 Answer 1

2

The problem you have is quite simple - in your example you have 2 ng-models, one is in the changecase, another in input. You add formatter to the first, but u need second. So your directive should be just:

app.directive('changecase', function () {
  return {
    restrict: 'E',
    scope: { model: '=model' },
    template: '<input realuppercase type="text" ng-model="model"> {{ model }}',
    link: function (scope, element, attrs) {
    }
  }
});

Just template, so you probably want to remove it. (I changed ng-model to model, cause here is simply no need in ngModel directive) And new realuppercase:

app.directive('realuppercase', function () {
  return {
    restrict: 'A',
    require: 'ngModel',
    link: function (scope, element, attrs, ctrl) {
      ctrl.$formatters.push(function(value) {
        return value.toUpperCase();
      });

      ctrl.$parsers.push(function(value) {
        return value.toLowerCase();
      });
    }
  }
});

Here is your modified plunk: http://plnkr.co/edit/UoSFFuCVnbAwerQYHc3o?p=preview (Type in caps -> model in lower case)

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

4 Comments

is that possible in one directive to have ngModelController came from the directive input template? I did +1 :)
You asking if you can access ngModelController from parent element? In normal way 'no' - you can use some tricks but usually it doesnt worth it.
yes I asking how to get that from parent,,what would be the way then? just for curiosity I wanted to know..Thanks anyways.. :)
@PetrAveryanov Thank you very much. A nice simple answer is what I was after, In my case I wanted the to be able to specify ng-model in the outer directive so that it's non standard so I changed my directive to transclude the outer one.

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.