格式化电话号码的指令

时间:2023-01-14 14:28:44

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 604-291-9283.

我想知道如何使用angularjs指令自动格式化输入字段中的数字?当我输入输入字段时说6042919283我希望它显示为604-291-9283。

Thanks

谢谢

7 个解决方案

#1


9  

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

您可以使用UI Utils掩码它允许您定义允许的输入格式,并将为您处理验证以及格式化

#2


7  

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

如果您的电话号码是统一的,即所有号码都是数字10,那么这个号码就可以了

  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;

和你的HTML;

<input type="text" id="phonenumber" ng-model="phonenumber" format-phone>

#3


4  

I've used the ui-mask directive in AngularUI to mask fields in the past with great success. The documentation isn't very helpful, but here's a simple example of how to make it work.

我在AngularUI中使用了ui-mask指令来掩盖过去的字段并取得了巨大的成功。文档不是很有用,但这是一个如何使其工作的简单示例。

Plunkr

Plunkr

  • Angular@1.4.1
  • Angular@1.4.1
  • Angular-UI-Utils@0.1.1
  • Angular-UI-Utils@0.1.1

#4


4  

Here is how I did it with a custom directive.

以下是我使用自定义指令的方法。

customDirective.js

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

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

HTML

<input type = "text" id="phonenumber" phone-input ng-model="USPhone" >
<p>{{USPhone | tel}}</p>

#5


1  

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

另外,我有一个验证器,invalidFormat,用户可以设置自定义消息,以防电话号码无效

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.

放置验证器的最佳位置是$ parsers,我从这里找到的证据中找到了答案:http://radify.io/blog/understanding-ngmodelcontroller-by-example-part-1/。这就是为什么我的答案与其他答案略有不同。

In the HTML

在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>

#6


1  

Custom directive for telephone format using angularjs

使用angularjs的电话格式的自定义指令

The field change format as user typing

用户输入时的字段更改格式

Restricts the input to numbers only

仅将输入限制为数字

Auto formats the input (541) 754-3010

自动格式化输入(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://*.com/a/30058928/6786941 ]

代码表格[https://*.com/a/30058928/6786941]

#7


1  

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.

不是这里任何答案的忠实粉丝所以想出了我自己的指示。它用空格格式化数字。不使用jquery,您不必跟踪击键。

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

#1


9  

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

您可以使用UI Utils掩码它允许您定义允许的输入格式,并将为您处理验证以及格式化

#2


7  

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

如果您的电话号码是统一的,即所有号码都是数字10,那么这个号码就可以了

  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;

和你的HTML;

<input type="text" id="phonenumber" ng-model="phonenumber" format-phone>

#3


4  

I've used the ui-mask directive in AngularUI to mask fields in the past with great success. The documentation isn't very helpful, but here's a simple example of how to make it work.

我在AngularUI中使用了ui-mask指令来掩盖过去的字段并取得了巨大的成功。文档不是很有用,但这是一个如何使其工作的简单示例。

Plunkr

Plunkr

  • Angular@1.4.1
  • Angular@1.4.1
  • Angular-UI-Utils@0.1.1
  • Angular-UI-Utils@0.1.1

#4


4  

Here is how I did it with a custom directive.

以下是我使用自定义指令的方法。

customDirective.js

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

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

HTML

<input type = "text" id="phonenumber" phone-input ng-model="USPhone" >
<p>{{USPhone | tel}}</p>

#5


1  

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

另外,我有一个验证器,invalidFormat,用户可以设置自定义消息,以防电话号码无效

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.

放置验证器的最佳位置是$ parsers,我从这里找到的证据中找到了答案:http://radify.io/blog/understanding-ngmodelcontroller-by-example-part-1/。这就是为什么我的答案与其他答案略有不同。

In the HTML

在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>

#6


1  

Custom directive for telephone format using angularjs

使用angularjs的电话格式的自定义指令

The field change format as user typing

用户输入时的字段更改格式

Restricts the input to numbers only

仅将输入限制为数字

Auto formats the input (541) 754-3010

自动格式化输入(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://*.com/a/30058928/6786941 ]

代码表格[https://*.com/a/30058928/6786941]

#7


1  

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.

不是这里任何答案的忠实粉丝所以想出了我自己的指示。它用空格格式化数字。不使用jquery,您不必跟踪击键。

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