Question 1 (mise en forme du numéro de téléphone):
Je dois formater un numéro de téléphone dans AngularJS mais il n'y a pas de filtre pour cela. Existe-t-il un moyen d'utiliser un filtre ou une devise pour formater 10 chiffres en (555) 555-5255
? et toujours conserver le type de données du champ sous forme d'entier?
Deuxième question (masquage du numéro de carte de crédit):
J'ai un champ de carte de crédit mappé sur AngularJS, tel que:
<input type="text" ng-model="customer.creditCardNumber">
qui renvoie le nombre entier (4111111111111111
). Je voudrais masquer avec xxx les 12 premiers chiffres et ne montrer que les 4 derniers. Je pensais utiliser un filtre: limite pour cela, mais je ne sais pas comment. Des idées? Est-il possible de formater également le nombre avec des tirets tout en conservant le type de données sous forme d'entier? sorte de 4111-1111-1111-1111
.
De plus, si vous devez formater le numéro de téléphone uniquement en sortie, vous pouvez utiliser un filtre personnalisé comme celui-ci:
angular.module('ng').filter('tel', function () {
return function (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 10: // +1PPP####### -> C (PPP) ###-####
country = 1;
city = value.slice(0, 3);
number = value.slice(3);
break;
case 11: // +CPPP####### -> CCC (PP) ###-####
country = value[0];
city = value.slice(1, 4);
number = value.slice(4);
break;
case 12: // +CCCPP####### -> CCC (PP) ###-####
country = value.slice(0, 3);
city = value.slice(3, 5);
number = value.slice(5);
break;
default:
return tel;
}
if (country == 1) {
country = "";
}
number = number.slice(0, 3) + '-' + number.slice(3);
return (country + " (" + city + ") " + number).trim();
};
});
Ensuite, vous pouvez utiliser ce filtre dans votre modèle:
{{ phoneNumber | tel }}
<span ng-bind="phoneNumber | tel"></span>
J'ai créé un module AngularJS pour gérer moi-même ce problème de numéros de téléphone avec une directive personnalisée et un filtre associé.
exemple jsfiddle: http://jsfiddle.net/aberke/s0xpkgmq/
Exemple d'utilisation du filtre: <p>{{ phonenumberValue | phonenumber }}</p>
Code de filtre:
.filter('phonenumber', function() {
/*
Format phonenumber as: c (xxx) xxx-xxxx
or as close as possible if phonenumber length is not 10
if c is not '1' (country code not USA), does not use country code
*/
return function (number) {
/*
@param {Number | String} number - Number that will be formatted as telephone number
Returns formatted number: (###) ###-####
if number.length < 4: ###
else if number.length < 7: (###) ###
Does not handle country codes that are not '1' (USA)
*/
if (!number) { return ''; }
number = String(number);
// Will return formattedNumber.
// If phonenumber isn't longer than an area code, just show number
var formattedNumber = number;
// if the first character is '1', strip it out and add it back
var c = (number[0] == '1') ? '1 ' : '';
number = number[0] == '1' ? number.slice(1) : number;
// # (###) ###-#### as c (area) front-end
var area = number.substring(0,3);
var front = number.substring(3, 6);
var end = number.substring(6, 10);
if (front) {
formattedNumber = (c + "(" + area + ") " + front);
}
if (end) {
formattedNumber += ("-" + end);
}
return formattedNumber;
};
});
Exemple d'utilisation de la directive:
<phonenumber-directive placeholder="'Input phonenumber here'" model='myModel.phonenumber'></phonenumber-directive>
Code de la directive:
.directive('phonenumberDirective', ['$filter', function($filter) {
/*
Intended use:
<phonenumber-directive placeholder='Prompt' model='someModel.phonenumber'></phonenumber-directive>
Where:
someModel.phonenumber: {String} value which to bind only the numeric characters [0-9] entered
ie, if user enters 617-2223333, value of 6172223333 will be bound to model
Prompt: {String} text to keep in placeholder when no numeric input entered
*/
function link(scope, element, attributes) {
// scope.inputValue is the value of input element used in template
scope.inputValue = scope.phonenumberModel;
scope.$watch('inputValue', function(value, oldValue) {
value = String(value);
var number = value.replace(/[^0-9]+/g, '');
scope.phonenumberModel = number;
scope.inputValue = $filter('phonenumber')(number);
});
}
return {
link: link,
restrict: 'E',
scope: {
phonenumberPlaceholder: '=placeholder',
phonenumberModel: '=model',
},
// templateUrl: '/static/phonenumberModule/template.html',
template: '<input ng-model="inputValue" type="tel" class="phonenumber" placeholder="{{phonenumberPlaceholder}}" title="Phonenumber (Format: (999) 9999-9999)">',
};
}])
Code complet avec module et comment l’utiliser: https://Gist.github.com/aberke/042eef0f37dba1138f9e
Comme Shailbenq l'a suggéré, phoneformat est génial.
Inclure le format du téléphone sur votre site Web. Créez un filtre pour le module angulaire ou votre application.
angular.module('ng')
.filter('tel', function () {
return function (phoneNumber) {
if (!phoneNumber)
return phoneNumber;
return formatLocal('US', phoneNumber);
}
});
Ensuite, vous pouvez utiliser le filtre dans votre code HTML.
{{phone|tel}}
OR
<span ng-bind="phone|tel"></span>
Si vous souhaitez utiliser le filtre dans votre contrôleur.
var number = '5553219876';
var newNumber = $filter('tel')(number);
J'ai aussi trouvé ce plugin JQuery facile à inclure dans votre application Angular (également avec bower: D) et vérifiant tous les codes de pays possibles avec leurs masques respectifs: intl-tel-input
Vous pouvez ensuite utiliser l'option validationScript
afin de vérifier la validité de la valeur de l'entrée.
Ceci est le moyen simple. Comme base, je l’ai prise à partir de http://codepen.io/rpdasilva/pen/DpbFf et j’ai fait quelques changements. Pour l'instant, le code est plus simplement . Et vous pouvez obtenir: dans le contrôleur - "4124561232", dans la vue "(412) 456-1232"
Filtre:
myApp.filter 'tel', ->
(tel) ->
if !tel
return ''
value = tel.toString().trim().replace(/^\+/, '')
city = undefined
number = undefined
res = null
switch value.length
when 1, 2, 3
city = value
else
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
res = ('(' + city + ') ' + number).trim()
else
res = '(' + city
return res
Et directive:
myApp.directive 'phoneInput', ($filter, $browser) ->
require: 'ngModel'
scope:
phone: '=ngModel'
link: ($scope, $element, $attrs) ->
$scope.$watch "phone", (newVal, oldVal) ->
value = newVal.toString().replace(/[^0-9]/g, '').slice 0, 10
$scope.phone = value
$element.val $filter('tel')(value, false)
return
return
Angular-ui a une directive pour masquer les entrées. C’est peut-être ce que vous voulez pour le masquage (malheureusement, la documentation n’est pas très bonne):
Je ne pense cependant pas que cela aidera à masquer le numéro de carte de crédit.
Vous pouvez également vérifier input mask formter.
Ceci est une directive appelée ui-mask
et qui fait également partie de angular-ui.utils
library.
Ici fonctionne: Exemple live
Pour le moment où cet article a été écrit, il n’existait aucun exemple d’utilisation de cette directive; j’ai donc créé un très exemple simple pour montrer comment cette chose fonctionne dans la pratique.
Essayez d'utiliser phoneformat.js ( http://www.phoneformat.com/ ), vous ne pouvez pas formater un numéro de téléphone uniquement en fonction des paramètres régionaux (en-US, ja-JP, fr-FR, de-DE, etc. ) mais valide également le numéro de téléphone. Sa bibliothèque très robuste basée sur le projet googles libphonenumber.
J'ai pris la solution d'Aberke et l'ai modifiée à mon goût.
Mon Code Pen
var myApp = angular.module('myApp', []);
myApp.controller('exampleController',
function exampleController($scope) {
$scope.user = { profile: {HomePhone: '(719) 465-0001 x1234'}};
$scope.homePhonePrompt = "Home Phone";
});
myApp
/*
Intended use:
<phone-number placeholder='Prompt' model='someModel.phonenumber' />
Where:
someModel.phonenumber: {String} value which to bind formatted or unformatted phone number
Prompt: {String} text to keep in placeholder when no numeric input entered
*/
.directive('phoneNumber',
['$filter',
function ($filter) {
function link(scope, element, attributes) {
// scope.inputValue is the value of input element used in template
scope.inputValue = scope.phoneNumberModel;
scope.$watch('inputValue', function (value, oldValue) {
value = String(value);
var number = value.replace(/[^0-9]+/g, '');
scope.inputValue = $filter('phoneNumber')(number, scope.allowExtension);
scope.phoneNumberModel = scope.inputValue;
});
}
return {
link: link,
restrict: 'E',
replace: true,
scope: {
phoneNumberPlaceholder: '@placeholder',
phoneNumberModel: '=model',
allowExtension: '=extension'
},
template: '<input ng-model="inputValue" type="tel" placeholder="{{phoneNumberPlaceholder}}" />'
};
}
]
)
/*
Format phonenumber as: (aaa) ppp-nnnnxeeeee
or as close as possible if phonenumber length is not 10
does not allow country code or extensions > 5 characters long
*/
.filter('phoneNumber',
function() {
return function(number, allowExtension) {
/*
@param {Number | String} number - Number that will be formatted as telephone number
Returns formatted number: (###) ###-#### x #####
if number.length < 4: ###
else if number.length < 7: (###) ###
removes country codes
*/
if (!number) {
return '';
}
number = String(number);
number = number.replace(/[^0-9]+/g, '');
// Will return formattedNumber.
// If phonenumber isn't longer than an area code, just show number
var formattedNumber = number;
// if the first character is '1', strip it out
var c = (number[0] == '1') ? '1 ' : '';
number = number[0] == '1' ? number.slice(1) : number;
// (###) ###-#### as (areaCode) prefix-endxextension
var areaCode = number.substring(0, 3);
var prefix = number.substring(3, 6);
var end = number.substring(6, 10);
var extension = number.substring(10, 15);
if (prefix) {
//formattedNumber = (c + "(" + area + ") " + front);
formattedNumber = ("(" + areaCode + ") " + prefix);
}
if (end) {
formattedNumber += ("-" + end);
}
if (allowExtension && extension) {
formattedNumber += ("x" + extension);
}
return formattedNumber;
};
}
);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="exampleController">
<p>Phone Number Value: {{ user.profile.HomePhone || 'null' }}</p>
<p>Formatted Phone Number: {{ user.profile.HomePhone | phoneNumber }}</p>
<phone-number id="homePhone"
class="form-control"
placeholder="Home Phone"
model="user.profile.HomePhone"
ng-required="!(user.profile.HomePhone.length || user.profile.BusinessPhone.length || user.profile.MobilePhone.length)" />
</div>
J'ai modifié le code pour que le téléphone sorte dans ce format Valeur: +38 (095) 411-22-23 Ici, vous pouvez le vérifier saisir le lien ici
var myApp = angular.module('myApp', []);
myApp.controller('MyCtrl', function($scope) {
$scope.currencyVal;
});
myApp.directive('phoneInput', 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,12);
});
// 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);
});
}
};
});
myApp.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, num1, num2, num3;
switch (value.length) {
case 1:
case 2:
case 3:
city = value;
break;
default:
country = value.slice(0, 2);
city = value.slice(2, 5);
num1 = value.slice(5,8);
num2 = value.slice(8,10);
num3 = value.slice(10,12);
}
if(country && city && num1 && num2 && num3){
return ("+" + country+" (" + city + ") " + num1 +"-" + num2 + "-" + num3).trim();
}
else if(country && city && num1 && num2) {
return ("+" + country+" (" + city + ") " + num1 +"-" + num2).trim();
}else if(country && city && num1) {
return ("+" + country+" (" + city + ") " + num1).trim();
}else if(country && city) {
return ("+" + country+" (" + city ).trim();
}else if(country ) {
return ("+" + country).trim();
}
};
});
Vous pouvez utiliser ng-pattern qui est plus facile et plus léger . http://tutorialzine.com/2014/12/learn-regular-expressions-in-20-minutes/ . Ici vous pouvez savoir à ce sujet , juste quelques mots significatifs , pas besoin de directive ou de filtre ,
Filtre simple qui ressemble à ceci (utilisez la classe numérique sur l'entrée et le caractère de filtre dans []):
<script type="text/javascript">
// Only allow number input
$('.numeric').keyup(function () {
this.value = this.value.replace(/[^0-9+-\.\,\;\:\s()]/g, ''); // this is filter for telefon number !!!
});
Trouvez Plunker pour formater les numéros de carte de crédit en utilisant la directive angularjs. Formater les numéros de carte en xxxxxxxxxxxxx3456 Fromat.
angular.module('myApp', [])
.directive('maskInput', function() {
return {
require: "ngModel",
restrict: "AE",
scope: {
ngModel: '=',
},
link: function(scope, elem, attrs) {
var orig = scope.ngModel;
var edited = orig;
scope.ngModel = edited.slice(4).replace(/\d/g, 'x') + edited.slice(-4);
elem.bind("blur", function() {
var temp;
orig = elem.val();
temp = elem.val();
elem.val(temp.slice(4).replace(/\d/g, 'x') + temp.slice(-4));
});
elem.bind("focus", function() {
elem.val(orig);
});
}
};
})
.controller('myCtrl', ['$scope', '$interval', function($scope, $interval) {
$scope.creditCardNumber = "1234567890123456";
}]);
J'ai également résolu ce problème avec un filtre angulaire personnalisé, mais le mien tire parti des groupes de capture de regex et le code est donc très court. Je l'associe à un filtre stripNonNumeric
distinct pour assainir l'entrée:
app.filter('stripNonNumeric', function() {
return function(input) {
return (input == null) ? null : input.toString().replace(/\D/g, '');
}
});
Le filtre phoneFormat
formate correctement un numéro de téléphone avec ou sans l'indicatif régional. (Je n'avais pas besoin d'un support de numéro international.)
app.filter('phoneFormat', function() {
//this establishes 3 capture groups: the first has 3 digits, the second has 3 digits, the third has 4 digits. Strings which are not 7 or 10 digits numeric will fail.
var phoneFormat = /^(\d{3})?(\d{3})(\d{4})$/;
return function(input) {
var parsed = phoneFormat.exec(input);
//if input isn't either 7 or 10 characters numeric, just return input
return (!parsed) ? input : ((parsed[1]) ? '(' + parsed[1] + ') ' : '') + parsed[2] + '-' + parsed[3];
}
});
Utilisez-les simplement:
<p>{{customer.phone | stripNonNumeric | phoneFormat}}</p>
La regex pour le filtre stripNonNumeric
provenait de ici .
Vous devrez créer des contrôles de formulaire personnalisés (sous forme de directives) pour le numéro de téléphone et la carte de crédit. Voir la section "Implémentation du contrôle de formulaire personnalisé (à l'aide de ngModel)" sur la page formulaires .
Comme Narretz l'a déjà mentionné, la directive de masque d'Angular-ui devrait vous aider à démarrer.
Voici comment j'ai créé la directive ssn qui vérifie le motif et j'ai utilisé RobinHerbots jquery.inputmask
angular.module('SocialSecurityNumberDirective', [])
.directive('socialSecurityNumber', socialSecurityNumber);
function socialSecurityNumber() {
var jquery = require('jquery');
var inputmask = require("jquery.inputmask");
return {
require: 'ngModel',
restrict: 'A',
priority: 1000,
link: function(scope,element, attr, ctrl) {
var jquery_element = jquery(element);
jquery_element.inputmask({mask:"***-**-****",autoUnmask:true});
jquery_element.on('keyup paste focus blur', function() {
var val = element.val();
ctrl.$setViewValue(val);
ctrl.$render();
});
var pattern = /^\d{9}$/;
var newValue = null;
ctrl.$validators.ssnDigits = function(value) {
newValue = element.val();
return newValue === '' ? true : pattern.test(newValue);
};
}
};
}