web-dev-qa-db-fra.com

Une directive pour formater le numéro de téléphone

Je me demandais comment formater automatiquement un nombre dans un champ en utilisant une directive angularjs? Lorsque je tape un champ d’entrée, par exemple 6042919283, je souhaite l’affichage du numéro 604-291-9283.

Merci

13
user1424508

Vous pouvez utiliser UI Utils mask Il vous permet de définir un format de saisie autorisé et gérera la validation pour vous ainsi que le formatage.

9
NadavSinai

Si votre numéro de téléphone est uniforme, c’est-à-dire que tous les numéros sont du chiffre 10, celui-ci fonctionnera.

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

                    });
                }
            };
        }
    ]);

Et votre html;

<input type="text" id="phonenumber" ng-model="phonenumber" format-phone>
7
BKM

Voici comment je l'ai fait avec une directive personnalisée.

customDirective.js

demoApp.directive('phoneInput', [ '$filter', '$browser', function($filter, $browser) {
return {
    require: 'ngModel',
    link: function($scope, $element, $attrs, ngModelCtrl) {
        var listener = function() {
            var value = $element.val().replace(/[^0-9]/g, '');
            $element.val($filter('tel')(value, false));
        };

        // This runs when we update the text field
        ngModelCtrl.$parsers.Push(function(viewValue) {
            return viewValue.replace(/[^0-9]/g, '').slice(0,10);
        });

        // This runs when the model gets updated on the scope directly and keeps our view in sync
        ngModelCtrl.$render = function() {
            $element.val($filter('tel')(ngModelCtrl.$viewValue, false));
        };

        $element.bind('change', listener);
        $element.bind('keydown', function(event) {
            var key = event.keyCode;
            // If the keys include the CTRL, SHIFT, ALT, or META keys, or the arrow keys, do nothing.
            // This lets us support copy and paste too
            if (key == 91 || (15 < key && key < 19) || (37 <= key && key <= 40)){
                return;
            }
            $browser.defer(listener); // Have to do this or changes don't get picked up properly
        });

        $element.bind('paste cut', function() {
            $browser.defer(listener);
        });
    }

};

}]);

Et en utilisant ce filtre personnalisé, vous pouvez filtrer le modèle.

customFilter.js

demoApp.filter('tel', function () {
return function (tel) {
    console.log(tel);
    if (!tel) { return ''; }

    var value = tel.toString().trim().replace(/^\+/, '');

    if (value.match(/[^0-9]/)) {
        return tel;
    }

    var country, city, number;

    switch (value.length) {
        case 1:
        case 2:
        case 3:
            city = value;
            break;

        default:
            city = value.slice(0, 3);
            number = value.slice(3);
    }

    if(number){
        if(number.length>3){
            number = number.slice(0, 3) + '-' + number.slice(3,7);
        }
        else{
            number = number;
        }

        return ("(" + city + ") " + number).trim();
    }
    else{
        return "(" + city;
    }

};

});

HTML

<input type = "text" id="phonenumber" phone-input ng-model="USPhone" >
<p>{{USPhone | tel}}</p>
5
Joel Raju

J'ai utilisé la directive ui-mask dans AngularUI pour masquer des champs dans le passé avec un grand succès. La documentation n'est pas très utile, mais voici un exemple simple montrant comment le faire fonctionner.

Plunkr

4
Walter Roman

J'ai écrit ça et ça marche plutôt bien. Le seul problème est que vous ne pouvez pas supprimer les tirets "-" du numéro. Ce code peut être facilement modifié pour en tenir compte.

De plus, j'ai un validateur, invalidFormat, qu'un utilisateur peut définir un message personnalisé au cas où le numéro de téléphone est invalide.

app.directive("phoneNumberValidator", function () {
    return {
        require: "ngModel",
        restrict: "A",
        link: function (scope, elem, attrs, ctrl) {

            var domElement = elem[0]; // Get DOM element
            var phoneNumberRegex = new RegExp("\\d{3}\\-\\d{3}\\-\\d{4}"); // Phone number regex
            var cursorIndex; // Index where the cursor should be

            // Create a parser to alter and validate if our
            // value is a valid phone number
            ctrl.$parsers.Push(function (value) {

                // If our value is non-existent, we return undefined
                // WHY?: an angular model value should be undefined if it is empty
                if (typeof value === "undefined" || value === null || value == "") {
                    ctrl.$setValidity('invalidFormat', true); // No invalid format if the value of the phone number is empty
                    return undefined;
                }

                // PARSER LOGIC
                // =compare our value to a modified value after it has
                // been transformed into a "Nice" phone number. If these
                // values are different, we set the viewValue to
                // the "Nice" phone number. If these values are the same,
                // we render the viewValue (aka. "Nice" phone number)
                var prevValue, nextValue;

                prevValue = value;
                nextValue = value.replace(/[\D]/gi, ""); // Strip all non-digits

                // Make the "Nice" phone number
                if (nextValue.length >= 4 && nextValue.length <= 6) {
                    nextValue = nextValue.replace(/(\d{3})(\d{3})?/, "$1-$2");
                } else if (nextValue.length >= 7 && nextValue.length <= 10) {
                    nextValue = nextValue.replace(/(\d{3})(\d{3})(\d{4})?/, "$1-$2-$3");
                }

                // Save the correct index where the custor should be
                // WHY?: we do this here because "ctrl.$render()" shifts
                // the cursor index to the end of the phone number
                cursorIndex = domElement.selectionStart;
                if (prevValue != nextValue) {
                    ctrl.$setViewValue(nextValue); // *Calling this function will run all functions in ctrl.$parsers!
                } else {
                     ctrl.$render(); // Render the new, "Nice" phone number
                }

                // If our cursor lands on an index where a dash "-" is,
                // move it up by one
                if (cursorIndex == 4 || cursorIndex == 8) {
                    cursorIndex = cursorIndex + 1;
                }

                var valid = phoneNumberRegex.test(value); // Test the validity of our phone number
                ctrl.$setValidity('invalidFormat', valid); // Set the validity of the phone number field
                domElement.setSelectionRange(cursorIndex, cursorIndex); // Assign the cursor to the correct index

                return value; // Return the updated value
            });
        }
    }
});

Le meilleur endroit pour mettre les validateurs est dans $ parsers, ce à quoi j'ai trouvé une réponse à partir des preuves trouvées ici: http://radify.io/blog/understanding-ngmodelcontroller-by-example-part-1/ - C'est pourquoi ma réponse est un peu différente des autres.

Dans le HTML

<input type="tel" class="form-control" id="PhoneNumber" name="PhoneNumber" ng-model="PhoneNumber" placeholder="Phone" maxlength="12" ng-value="PhoneNumber" required phone-number-validator server-validation>
<p class="help-block" ng-if="PhoneNumber.$error.invalidFormat">Phone Number is invalid</p>
1
Zac

N'étais pas un grand fan de l'une des réponses ici, donc est venu avec une directive de ma part. Il formate le nombre avec un espace blanc. N'utilise pas jQuery et vous n'avez pas à suivre les touches.

.directive('reformatPhoneNumber', function() {
    return {
      require: 'ngModel',
      link: function(scope, element, attrs, modelCtrl) {

        modelCtrl.$parsers.Push(function(number) {
          var transformedNumber = number;

          if (number.match(/^\d{4}$/)) {
            transformedNumber = number.slice(0, 3) + " " + number.slice(3);
          }
          if(number.match(/^[\d\s]{8}$/)){
            transformedNumber = number.slice(0, 7) + " " + number.slice(7);
          }

          if (number.length > 12) {
            transformedNumber = number.slice(0, 12);
          }
          if (transformedNumber !== number) {
            modelCtrl.$setViewValue(transformedNumber);
            modelCtrl.$render();
          }
          return transformedNumber;
        });
      }
    };
  });
1
Joe Komputer

Directive personnalisée pour le format téléphonique utilisant angularjs

Le format de champ change lorsque l'utilisateur tape 

Limite l'entrée aux nombres uniquement

Formate automatiquement l'entrée _ {(541) 754-3010

app.directive("phoneNumberValidator", function () {
        return {	
            restrict: 'A',
			link: function (scope, elem, attrs, ctrl, ngModel) {
				elem.add(phonenumber).on('keyup', function () {
					var input = elem.val();
					// Strip all characters from the input except digits
					input = input.replace(/\D/g, '');

					// Trim the remaining input to ten characters, to preserve phone number format
					input = input.substring(0, 10);

					// Based upon the length of the string, we add formatting as necessary
					var size = input.length;
					if (size == 0) {
						input = input;
					} else if (size < 4) {
						input = '(' + input;
					} else if (size < 7) {
						input = '(' + input.substring(0, 3) + ') ' + input.substring(3, 6);
					} else {
						input = '(' + input.substring(0, 3) + ') ' + input.substring(3, 6) + ' - ' + input.substring(6, 10);
					}
					jQuery("#phonenumber").val(input);
				});
			}
		}
    });

formulaire de code [ https://stackoverflow.com/a/30058928/6786941 ]

1
Amr Ibrahim