A directive to format phone number

后端 未结 7 1816
梦毁少年i
梦毁少年i 2021-01-02 00:33

I was wondering how to automatically format a number in an input field using an angularjs directive? When I type in an input field say 6042919283 I want it to be shown as 6

相关标签:
7条回答
  • 2021-01-02 01:10

    You could use UI Utils mask It allows you to define an allowd input format and will handle the validation for you as well as the formatting

    0 讨论(0)
  • 2021-01-02 01:12

    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;
            });
          }
        };
      });
    
    0 讨论(0)
  • 2021-01-02 01:18

    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 ]

    0 讨论(0)
  • 2021-01-02 01:20

    I wrote this, and works pretty well. The only catch is you cannot delete dashes "-" in the number. This code can be easily modified to account for that.

    In addition, I have a validator, invalidFormat that a user can set a custom message in case the phone number is invalid

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

    The best place to put validators is in $parsers, which I found my answer from evidence found here: http://radify.io/blog/understanding-ngmodelcontroller-by-example-part-1/. This is why my answer is a bit different than the others.

    In the 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>
    
    0 讨论(0)
  • 2021-01-02 01:24

    If your phone number is uniform i.e all the number is of digit 10 this one will work

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

    And your html;

    <input type="text" id="phonenumber" ng-model="phonenumber" format-phone>
    
    0 讨论(0)
  • 2021-01-02 01:25

    Here is how I did it with a custom directive.

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

    And using this custom filter you can filter the model.

    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>
    
    0 讨论(0)
提交回复
热议问题