Форматирование номеров телефонов и кредитных карт в AngularJS
Вопрос один (номер телефона для форматирования):
Мне нужно отформатировать телефонный номер в AngularJS, но для него нет фильтра. Есть ли способ использовать фильтр или валюту для форматирования 10 цифр до (555) 555-5255
? и сохраните тип данных поля как целое?
Вопрос два (маскировка номера кредитной карты):
У меня есть поле кредитной карты, которое отображается на AngularJS, например:
<input type="text" ng-model="customer.creditCardNumber">
который возвращает все число (4111111111111111
). Я хотел бы скрыть его с помощью xxx первых 12 цифр и показать только 4 последних. Я думал об использовании фильтра: предел для этого, но я не понимаю, как это сделать. Есть идеи? Есть ли способ форматировать число с тире, но сохранить тип данных как целого? тип 4111-1111-1111-1111
.
Ответы
Ответ 1
Кроме того, если вам нужно отформатировать номер телефона только на выходе, вы можете использовать настраиваемый фильтр, подобный этому:
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();
};
});
Затем вы можете использовать этот фильтр в своем шаблоне:
{{ phoneNumber | tel }}
<span ng-bind="phoneNumber | tel"></span>
Ответ 2
Я создал модуль AngularJS, чтобы справиться с этой проблемой в отношении phonenumbers для себя с помощью настраиваемой директивы и сопутствующего фильтра.
Пример jsfiddle: http://jsfiddle.net/aberke/s0xpkgmq/
Пример использования фильтра: <p>{{ phonenumberValue | phonenumber }}</p>
Код фильтра:
.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;
};
});
Пример использования директивы:
<phonenumber-directive placeholder="'Input phonenumber here'" model='myModel.phonenumber'></phonenumber-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)">',
};
}])
Полный код с модулем и как его использовать:
https://gist.github.com/aberke/042eef0f37dba1138f9e
Ответ 3
Как предположил shailbenq, phoneformat является удивительным.
Включите формат телефона на своем веб-сайте. Создайте фильтр для модуля angular или вашего приложения.
angular.module('ng')
.filter('tel', function () {
return function (phoneNumber) {
if (!phoneNumber)
return phoneNumber;
return formatLocal('US', phoneNumber);
}
});
Затем вы можете использовать фильтр в своем HTML.
{{phone|tel}}
OR
<span ng-bind="phone|tel"></span>
Если вы хотите использовать фильтр в контроллере.
var number = '5553219876';
var newNumber = $filter('tel')(number);
Ответ 4
![enter image description here]()
Я также нашел, что плагин JQuery, который легко включить в ваше приложение Angular (также с bower: D), и который проверяет все возможные коды стран с соответствующими масками:
intl-tel-input
Затем вы можете использовать параметр validationScript
, чтобы проверить правильность введенного значения.
Ответ 5
Angular -ui имеет директиву для ввода маскировки. Возможно, это то, что вы хотите для маскировки (к сожалению, документация не так уж и хороша):
http://angular-ui.github.com/
Я не думаю, что это поможет с запутыванием номера кредитной карты.
Ответ 6
Вы также можете проверить форматирование маски ввода.
Это директива, которая называется ui-mask
, а также она является частью angular-ui.utils
.
Здесь работает: Живой пример
На момент написания этого сообщения нет примеров использования этой директивы, поэтому я сделал очень простой пример, чтобы продемонстрировать, как эта вещь работает на практике.
Ответ 7
Это простой способ. В качестве основного я взял его из http://codepen.io/rpdasilva/pen/DpbFf и внес некоторые изменения. На данный момент код проще.
И вы можете получить: в контроллере - " 4124561232", в поле зрения " (412) 456-1232"
Фильтр:
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
И директива:
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
Ответ 8
Попробуйте использовать phoneformat.js(http://www.phoneformat.com/), вы можете не только форматировать номер телефона на основе пользовательских мест (en-US, ja -JP, fr-FR, de-DE и т.д.), Но также проверяет номер телефона. Его очень надежная библиотека, основанная на проекте googles libphonenumber.
Ответ 9
Вы можете использовать ng-pattern, который легче и легче.
http://tutorialzine.com/2014/12/learn-regular-expressions-in-20-minutes/.
Здесь вы можете знать об этом,, просто некоторые значимые слова,, не нуждается в какой-либо директиве или фильтре,,
Ответ 10
Я принял решение aberke и модифицировал его в соответствии с моим вкусом.
- Он создает один элемент ввода
- Он может принимать расширения
- Для номеров в США он пропускает код страны
- Стандартные соглашения об именах
- Использует класс для использования кода; не составляет класс
- Позволяет использовать любые другие атрибуты, разрешенные для элемента ввода
My 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>
Ответ 11
Я изменил код для вывода телефона в этом формате. Значение: +38 (095) 411-22-23
Здесь вы можете проверить его ввести описание ссылки здесь
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();
}
};
});
Ответ 12
Вам нужно будет создать собственные элементы управления формой (в качестве директив) для номера телефона и кредитной карты. См. Раздел "Внедрение настраиваемого элемента управления формой (с помощью ngModel)" на странице forms.
Как уже упоминал Наррец, Angular -ui Маска директива должна помочь вам начать.
Ответ 13
Простой фильтр что-то вроде этого (используйте числовой класс для фильтра конца входного фильтра в []):
<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 !!!
});
Ответ 14
Вот как я создал директиву ssn, которая проверяет шаблон, и я использовал 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);
};
}
};
}
Ответ 15
Я решил эту проблему с помощью настраиваемого фильтра Angular, но мой использует преимущества групп захвата regex, и поэтому код действительно короткий. Я соединяю его с отдельным фильтром stripNonNumeric
для дезинфекции ввода:
app.filter('stripNonNumeric', function() {
return function(input) {
return (input == null) ? null : input.toString().replace(/\D/g, '');
}
});
Фильтр phoneFormat
правильно форматирует телефонный номер с кодом города или без него. (Мне не нужна поддержка международного номера.)
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];
}
});
Используйте их просто:
<p>{{customer.phone | stripNonNumeric | phoneFormat}}</p>
Регулярное выражение для фильтра stripNonNumeric
произошло от здесь.
Ответ 16
Найти Plunker для форматирования номеров кредитных карт, используя директиву angularjs. Форматировать номера карт в xxxxxxxxxxxx3456 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";
}]);
Ответ 17
Вставить "xeditable" модуль в ваше приложение angular (свободно доступно):
var App = angular.module('App', ['xeditable']);
И затем используйте встроенную функцию в своем HTML-коде следующим образом:
<div>{{ value|number:2 }}</div>