Vincent
Vincent

Reputation: 6188

Filter input with directive

html

<input type="text" name="usernr" ng-model="userNr" placeholder="user nr"
                               tabindex="2" ng-usernumber/>

javascript

app.directive('ngUserNumber', function() {
            return {
                restrict: 'A',
                require: 'ngModel',
                link: function(scope, elm, attrs, ctrl) {
                    console.log("inside directive");
                    ctrl.$parsers.push(function(data) {
                        console.log("//convert data from view format to model format");

                        data = data.toString() + " test";

                        return data; //converted
                    });

                    ctrl.$formatters.push(function(data) {
                        console.log("//convert data from model format to view format");

                        data = data.toString() + " test";

                        return data; //converted
                    });
                }
            };
        });

I would like to replace the data provided by ng-model, with data from inside the directive. But nothing happens. How come the custom directive isn't used?

I followed this doc: http://www.ng-newsletter.com/posts/directives.html
other source: https://stackoverflow.com/a/15346236/489856

Upvotes: 1

Views: 564

Answers (2)

sad comrade
sad comrade

Reputation: 1501

In order to reflect changes to the current input you need to call

ctrl.$setViewValue(transformedInput);
ctrl.$render();

Found solution here

Quote from docs:

In any case, the value passed to the method should always reflect the current value of the control. For example, if you are calling $setViewValue for an input element, you should pass the input DOM value. Otherwise, the control and the scope model become out of sync. It's also important to note that $setViewValue does not call $render or change the control's DOM value in any way. If we want to change the control's DOM value programmatically, we should update the ngModel scope expression. Its new value will be picked up by the model controller, which will run it through the $formatters, $render it to update the DOM, and finally call $validate on it.

Upvotes: 0

Thomas Pons
Thomas Pons

Reputation: 7729

Do it just like that :

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

app.controller('MyCtrl', function($scope){

  });

app.directive('ngUsernumber', function() {
            return {
                restrict: 'A',
                require: 'ngModel',
                link: function(scope, elm, attrs, ctrl) {

                    var format = function(data){
                        console.log("//convert data from view format to model format");

                        if(data !== undefined){
                          data = data.toString() + " test";
                        }


                        return data; //converted
                    };

                    ctrl.$parsers.push(format)
                    ctrl.$formatters.push(format);

                }
            };
        });

Working plunkr here : http://plnkr.co/edit/iA85KC?p=preview

You have to respect CamelCase for your directive note : ngUsernumber -> ng-usernumber if you do ngUserNumber -> ng-user-number

Hope it helps !

Upvotes: 1

Related Questions