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
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.
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>
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>
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.
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>
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;
});
}
};
});
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 ]