Une directive pour formater le numéro de téléphone
Question
Je me demandais comment formater automatiquement un nombre dans un champ de saisie à l'aide d'une directive angulairejs ?Lorsque je tape dans un champ de saisie, dites 6042919283, je souhaite qu'il s'affiche sous la forme 604-291-9283.
Merci
La solution
Vous pouvez utiliser masque UI UTIS Il vous permet de définir un format d'entrée Autoryd et gérera la validation pour vous ainsi que le formatage
Autres conseils
Si votre numéro de téléphone est uniforme, tout le nombre est de 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.
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é le ui-mask
directive dans Interface utilisateur angulaire masquer des champs dans le passé avec beaucoup de succès.La documentation n'est pas très utile, mais voici un exemple simple de la façon de la faire fonctionner.
- Angulaire@1.4.1
- Angulaire-UI-Utils@0.1.1
J'ai écrit cela et ça marche assez bien.La seule prise est que vous ne pouvez pas supprimer les tirets "-" dans le numéro.Ce code peut être facilement modifié pour tenir compte de cela.
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 en $ des analyseurs, que j'ai trouvé ma réponse des preuves trouvées ici: http://radiify.io/blog/unSerStanding-ngModelController-By-example-partver-/ .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>
Custom directive for telephone format using angularjs
The field change format as user typing
Restricts the input to numbers only
Auto formats the input (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);
});
}
}
});
code form [ https://stackoverflow.com/a/30058928/6786941 ]
Wasn't a big fan of any of the answers here so came up with a directive of my own. It formats number with white space. Doesn't use jquery and you don't have to track key strokes.
.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;
});
}
};
});