Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular phone number directive using intl-tel-input lib

I am currently trying to create a custom directive that would initialize an input with the following lib : intl-tel-input .

So I downloaded the required .js file with bower:

<script src="bower_components/intl-tel-input/build/js/intlTelInput.min.js"></script>

Then I create my input :

input type="tel" class="form-control" id="tel" name="tel" ng-model="informations.tel" ng-keyup="checkPhoneFormat()" ng-click="checkPhoneFormat()">

And I'm initializing it at the beginning of my controller like this :

angular.element('#tel).intlTelInput({
    validationScript: "../../bower_components/intl-tel-input/lib/libphonenumber/build/isValidNumber.js",
    preferredCountries: ['en', 'fr']
});

My problem is that when I'm trying to access the informations.telmodel, it is always undefined. It seems that the input do not update the model value on the fly.

So I have to write something like this to bind the actual value of my input field with my non updated model value :

    $scope.checkPhoneFormat = function(){
        $scope.informations.telephone = angular.element('#telephone').val();
        ...}

It could be ok but I would like to create a custom directive to initialize such inputs, something like :

app.directive('phoneInput', function (PhoneFactory) {
    return {
        require: 'ngModel',
        restrict: 'A',
        scope: {
            phoneNumber: '='
        },
        link: function (scope, element, attrs, ctrl) {
            element.intlTelInput({
                 validationScript: "../../bower_components/intl-tel-input/lib/libphonenumber/build/isValidNumber.js",
                 preferredCountries: ['en', 'fr']
            });

            ctrl.$parsers.unshift(function(viewValue) {
                console.log(viewValue);
            });
        }
    };
});

But as ngModel is undefined the initialization function is never reached... Do you have any idea how I could solve my problem?

like image 323
lightalex Avatar asked Jul 15 '14 08:07

lightalex


4 Answers

You are right that the model does not get updated automatically. You could make a directive like this

app.directive('intlTel', function(){
  return{
    replace:true,
    restrict: 'E',
    require: 'ngModel',
    template: '<input type="text" placeholder="e.g. +1 702 123 4567">',
    link: function(scope,element,attrs,ngModel){
      var read = function() {
        var inputValue = element.val();
        ngModel.$setViewValue(inputValue);
      }      
      element.intlTelInput({
        defaultCountry:'fr',
      });
      element.on('focus blur keyup change', function() {
          scope.$apply(read);
      });
      read();
    }
  }
});

that could be called like this

<intl-tel ng-model="model.telnr"></intl-tel>

Here is a Plunker

like image 62
Edminsson Avatar answered Nov 15 '22 07:11

Edminsson


There is a new directive called international-phone-number @ https://github.com/mareczek/international-phone-number

Please checkout, any contributions are welcome

like image 31
MarkP Avatar answered Nov 15 '22 08:11

MarkP


A few of us used Marks's directive, but the lack of testing and jquery's required position in the head was causing issues so ng-intl-tel-input was created:

https://github.com/hodgepodgers/ng-intl-tel-input

Check it out, it's unit and functionally tested with protractor Play with it here:

http://hodgepodgers.github.io/ng-intl-tel-input/

like image 45
John Lozano Avatar answered Nov 15 '22 08:11

John Lozano


Mark's directive worked for me: https://github.com/mareczek/international-phone-number

One issue with intl-tel-input (at least with v3.6) is that it doesn't format the phone number you initialize it with properly* unless you have a plus sign ('+') before it. This leads to funky behavior for my users. I store my phone numbers normalized (without the plus sign) in my database so I need a hack to get around this. Instead of formatting on the server, I opted to format the phone number on the front-end. I added the following to Mark's directive to get the behavior I needed:

var makeSureInitialValueStartsWithPlusSign = function() {
  var clear_watcher = scope.$watch(attrs.ngModel, function(changes) {
    elem_val = element.val();
    if (elem_val && elem_val[0] != "+") {
      element.val("+" + changes);
      clear_watcher();
    }
  });
};
makeSureInitialValueStartsWithPlusSign();

Thanks Mark

*By properly I mean converting '19734566789' to '+1 973-456-6789'. int-tel-input converts '19734566789' to '1 973-456-6789' (without the pus). When a user goes to edit it, they experience whacky behavior because the plus is not there.

like image 41
mr_mariusz Avatar answered Nov 15 '22 06:11

mr_mariusz