在AngularJS中格式化电话和信用卡号码

在AngularJS中格式化电话和信用卡号码,angularjs,number-formatting,Angularjs,Number Formatting,问题一(格式化电话号码): 我必须用AngularJS格式化一个电话号码,但是没有过滤器。是否有办法使用过滤器或货币将10位数字格式化为(555)555-5255?是否仍将字段的数据类型保留为整数 问题二(隐藏信用卡号码): 我有一个映射到AngularJS的信用卡字段,如: <input type="text" ng-model="customer.creditCardNumber"> 返回整数(4111111111)。我想用xxx屏蔽它的前12位,只显示最后4位。我正在考

问题一(格式化电话号码):

我必须用AngularJS格式化一个电话号码,但是没有过滤器。是否有办法使用过滤器或货币将10位数字格式化为
(555)555-5255
?是否仍将字段的数据类型保留为整数

问题二(隐藏信用卡号码):

我有一个映射到AngularJS的信用卡字段,如:

<input type="text" ng-model="customer.creditCardNumber"> 


返回整数(
4111111111
)。我想用xxx屏蔽它的前12位,只显示最后4位。我正在考虑使用过滤器:限制,但不清楚如何使用。有什么想法吗?是否有一种方法也可以使用破折号格式化数字,但仍将数据类型保留为整数?sort of
4111-1111-1111-1111

角度ui有一个屏蔽输入的指令。也许这就是您想要屏蔽的内容(不幸的是,文档不是很好):


不过,我认为这无助于混淆信用卡号码。

您需要为电话号码和信用卡创建自定义表单控件(作为指令)。请参见第页的“实现自定义表单控件(使用ngModel)”一节


正如Narretz已经提到的,Angular ui应该可以帮助您入门。

此外,如果您只需要在输出上格式化电话号码,您可以使用如下自定义筛选器:

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>
{{phoneNumber | tel}
尝试使用phoneformat.js(),您不仅可以根据用户区域设置(en-US、ja-JP、fr-fr、de-de等)格式化电话号码,还可以验证电话号码。其基于谷歌libphonenumber项目的非常强大的库。

正如shailbenq所建议的,非常棒

在您的网站中包含电话格式。为角度模块或应用程序创建过滤器

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>

我还发现JQuery插件很容易包含在Angular应用程序中(也包括bower:D),它可以用各自的掩码检查所有可能的国家代码:


然后,您可以使用
validationScript
选项来检查输入值的有效性。

我创建了一个AngularJS模块,通过自定义指令和附带的过滤器为自己处理有关电话号码的问题

JSFIDLE示例:

过滤器使用示例:
{{phonenumberValue}

过滤代码:

.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;
    };
});
.filter('phonenumber',function(){
/* 
电话号码格式为:c(xxx)xxx xxxx
或者,如果电话号码长度不是10,则尽可能接近
如果c不是“1”(国家代码不是美国),则不使用国家代码
*/
返回函数(编号){
/* 
@param{Number | String}Number-将被格式化为电话号码的号码
返回格式化的数字:(####)###-####
如果number.length<4:###
如果number.length小于7,则为else:(####)###
不处理非“1”的国家代码(美国)
*/
如果(!number){返回“”;}
数字=字符串(数字);
//将返回格式化的数字。
//如果电话号码不超过区号,只需显示号码即可
var formattedNumber=编号;
//如果第一个字符是“1”,请将其去掉并重新添加
变量c=(数字[0]='1')?'1':'';
数字=数字[0]=“1”?数字。切片(1):数字;
//###########-####作为c(区域)前端
var面积=子串数(0,3);
var front=子串的数量(3,6);
var end=子字符串(6,10)的数量;
如果(前面){
格式化编号=(c+“(“+区域+”)+正面);
}
若(完){
格式化数字+=(“-”+结束);
}
返回格式化的数字;
};
});
指令使用示例:

<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)">',
    };
}])
.directive('phonenumberDirective',['$filter',function($filter){
/*
预期用途:
哪里:
someModel.phonenumber:{String}值,仅绑定输入的数字字符[0-9]
即,如果用户输入617-222333,则6172223333的值将绑定到模型
提示:{String}未输入数字时保留在占位符中的文本
*/
功能链接(范围、元素、属性){
//scope.inputValue是模板中使用的输入元素的值
scope.inputValue=scope.phonenumberModel;
作用域.$watch('inputValue',函数(value,oldValue){
值=字符串(值);
变量编号=值。替换(/[^0-9]+//g');
scope.phonenumberModel=数字;
scope.inputValue=$filter('phonenumber')(数字);
});
}
返回{
链接:链接,
限制:'E',
范围:{
phonenumberPlaceholder:“=占位符”,
phonenumberModel:'=模型',
},
//templateUrl:“/static/phonenumberModule/template.html”,
模板:“”,
};
}])
模块的完整代码和使用方法:

您还可以检查输入掩码格式化程序

这是一个指令,叫做
ui-mask
,也是库的一部分

这里有工作:

在写这篇文章的时候,没有任何使用这个指令的例子,所以我做了一个非常简单的例子来演示这个东西在实践中是如何工作的


您可以使用更简单、更轻的ng图案。 .
在这里,你可以了解它,,,只是一些有意义的词,,,不需要任何指令或过滤器,,,,,,,,,

这是简单的方法。作为基础,我从中获取了它,并做了一些更改。目前,代码更加简单。 您可以得到:在控制器-“4124561232”中,在视图“(412)456”中-
.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)">',
    };
}])
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
<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 !!!
});
    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();
        }

    };
});
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);    
            };
        }
    };
}
app.filter('stripNonNumeric', function() {
    return function(input) {
        return (input == null) ? null : input.toString().replace(/\D/g, '');
    }
});
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>
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";
  }]);