Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Format telephone and credit card numbers in AngularJS

Question one (formatting telephone number):

I'm having to format a telephone number in AngularJS but there is no filter for it. Is there a way to use filter or currency to format 10 digits to (555) 555-5255? and still preserve the data type of the field as integer?

Question two (masking credit card number):

I have a credit card field that is mapped to AngularJS, like:

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

which is returning the whole number (4111111111111111). I will like to mask it with xxx the first 12 digits and only show the last 4. I was thinking on using filter: limit for this but am not clear as how. Any ideas? Is there a way to also format the number with dashes but still retain the data type as integer? sort of 4111-1111-1111-1111.

like image 406
J Castillo Avatar asked Oct 02 '12 23:10

J Castillo


4 Answers

Also, if you need to format telephone number on output only, you can use a custom filter like this one:

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();
    };
});

Then you can use this filter in your template:

{{ phoneNumber | tel }}
<span ng-bind="phoneNumber | tel"></span>
like image 135
kstep Avatar answered Oct 17 '22 10:10

kstep


I created an AngularJS module to handle this issue regarding phonenumbers for myself with a custom directive and accompanying filter.

jsfiddle example: http://jsfiddle.net/aberke/s0xpkgmq/

Filter use example: <p>{{ phonenumberValue | phonenumber }}</p>

Filter code:

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

Directive use example:

<phonenumber-directive placeholder="'Input phonenumber here'" model='myModel.phonenumber'></phonenumber-directive>

Directive code:

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

Full code with module and how to use it: https://gist.github.com/aberke/042eef0f37dba1138f9e

like image 33
aberke Avatar answered Oct 17 '22 10:10

aberke


As shailbenq suggested, phoneformat is awesome.

Include phone format in your website. Create a filter for the angular module or your application.

angular.module('ng')
.filter('tel', function () {
    return function (phoneNumber) {
        if (!phoneNumber)
            return phoneNumber;

        return formatLocal('US', phoneNumber); 
    }
});

Then you can use the filter in your HTML.

{{phone|tel}} 
OR
<span ng-bind="phone|tel"></span>

If you want to use the filter in your controller.

var number = '5553219876';
var newNumber = $filter('tel')(number);
like image 13
Michael DePetrillo Avatar answered Oct 17 '22 12:10

Michael DePetrillo


enter image description here

I also found that JQuery plugin that is easy to include in your Angular App (also with bower :D ) and which check all possible country codes with their respective masks : intl-tel-input

You can then use the validationScript option in order to check the validity of the input's value.

like image 11
lightalex Avatar answered Oct 17 '22 10:10

lightalex