reknirt
reknirt

Reputation: 2254

Directive doesn't update scope variable

I have a directive that formats a phone number to (xxx) xxx-xxxx. The formatting works as expected, however, the model on the input field isn't updating unless you enter one character passed the standard 10. So after the user enters 10 digits the number automatically formats inside of the input field. But the scope variable set on ng-model does not save the formatting unless you enter an additional character.

Here's the directive:

(function (app) {
  'use strict';

  app.directive('formatPhone', [
    function() {
      return {
        require: 'ngModel',
        restrict: 'A',
        link: function(scope, elem) {
          elem.on('keyup', function() {
            var origVal = elem.val().replace(/[^\d]/g, '');
            if(origVal.length === 10) {
              var str = origVal.replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');
              var phone = str.slice(0, -1) + str.slice(-1);
              jQuery('#phonenumber').val(phone);
            }

          });
        }
      };
    }
  ]);
}(window.app));

And here is the input field, using the directive as an attribute:

<input type="text" placeholder="Phone" name="phone" id="phonenumber" class="user-search-input create-short form-control" ng-model="userCtrl.userPost.user.phoneNumber" required format-phone>

I've tried adding a $watch to it, also with no luck.

Upvotes: 0

Views: 447

Answers (1)

Whisher
Whisher

Reputation: 32716

Try like

.directive('formatPhone', [
    function() {
        return {
            require: 'ngModel',
            restrict: 'A',
            priority:999999, //<-- Give a higher priority
            scope: {         
                model:'=ngModel' //<-- A 2 way binding to read actual bound value not the ngModel view value
            },
            link: function(scope, elem, attrs, ctrl) {
                var unwatch = scope.$watch('model', function(val){
                        if(!val) return;
                        var origVal = val.replace(/[^\d]/g, '');
                        if(origVal.length === 10) {
                            var str = origVal.replace(/(\d{3})(\d{3})(\d{4})/, '($1) $2-$3');
                            var phone = str.slice(0, -1) + str.slice(-1);
                            ctrl.$setViewValue(phone);
                            ctrl.$render();
                            unwatch();
                        }
                 });
            }
        };
    }
]);

Upvotes: 2

Related Questions