0

I'm working on a directive made for <input> that watches what the user types. When the user types in a valid phone number it should re-format the input model object and set a variable to true, indicating to the parent scope that the model now contains a valid phone number.

CountryISO is depency injected as constant and contains - surprise - the country code of the user. The functions used inside the directive are from phoneformat.js

UPDATED: Now the valid = true/false assigment works. But how do I then update the actual model value? This needs to be changed to the properly formatted phone number.

app.directive('phoneFormat', ['CountryISO', function (CountryISO) {
            return {
                restrict: 'A',
                require: 'ngModel',
                scope: {
                    valid:'='
                },
                link: function (scope, element, attrs, ngModel) {

                scope.$watch(function() {
                return ngModel.$viewValue; //will return updated ng-model value
                }, function(v) {

                if (isValidNumber(v, CountryISO)) {

                    // What do I do here? This doesn't work.
                    v = formatE164(CountryISO, v);
                    // This neither
                    ngModel.$viewValue = formatE164(CountryISO, v);

                    console.log("valid");
                    scope.valid = true;

                } else {

                    console.log("invalid");
                    scope.valid = false;
                }
                });
                }
            };
        }]);

as the directive

and the html looks like:

<input data-phone-format data-valid="user.validPhoneNumber" data-ng-model="user.info.ph">

The problem is that as soon as I include scope: {valid:'='}, as part of the directive, the $watch stops working. How do I get both? I want the directive to be able to point to a variable in the parent scope that should change from true to false depending on the validity of the phone number.

nickdnk
  • 4,010
  • 4
  • 24
  • 43

1 Answers1

1

Because as you declaring watcher the variable are parsing with the directive scope which becomes isolated scope after you have added scope: {valid:'='} to make it working you could place watch on the ngModel.$viewValue

To updated the ngModel value you could set $viewValue of ngModel using $setViewValue method of ngModel & then to update that value inside $modelValue you need to do $render() on ngModel.

Read on $viewValue & $modelValue

Link

link: function(scope, element, attrs, ngModel) {

    scope.$watch(function() {
        return ngModel.$viewValue; //will return updated ng-model value
    }, function(v) {

        if (isValidNumber(v, CountryISO)) {

            // What do I do here? This doesn't work.
            v = formatE164(CountryISO, v);
            // This neither
            ngModel.$setViewValue(formatE164(CountryISO, v));
            ngModel.$render(); //to updated the $modelValue of ngModel
            console.log("valid");
            scope.valid = true;

        } else {

            console.log("invalid");
            scope.valid = false;
        }
    });
}
Community
  • 1
  • 1
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
  • $viewValue comes from where? Is this something I must declare somewhere? – nickdnk Sep 27 '15 at 14:00
  • @nickdnk it came from `require`, you need to add that inside link function parameter..look at the updated answer.. – Pankaj Parkar Sep 27 '15 at 14:06
  • $viewValue is a property on the ngModelController, which you `require`-d. – XML Sep 27 '15 at 14:08
  • Ok. Cool. It works. Does that mean I don't need element and attr as arguments? – nickdnk Sep 27 '15 at 14:08
  • @nickdnk no you meant it wrong way..I said that `require` of directive options like you specified here `require: 'ngModel',` you have to add `element` & `attrs`, the 4th parameter would only be `requireController` or `transcludeFn` depends what you are doing – Pankaj Parkar Sep 27 '15 at 14:11
  • @PankajParkar Yes - your changes made the watching work properly. Please see the updated question. – nickdnk Sep 27 '15 at 14:23
  • Amazing. Exactly what I needed. Thanks a lot. – nickdnk Sep 27 '15 at 14:29
  • 1
    @nickdnk Glad to help you..Thanks :) you could read up on linked answer for more into on `$viewValue` & `$modelValue` – Pankaj Parkar Sep 27 '15 at 14:30