(Angular2/4/5/6) 如何根据国家/地区验证国际 phone 号码的长度
(Angular2/4/5/6) How to validate length of international phone numbers according to country
是否有 library/service class 可用于单独验证国际手机号码?例如。新加坡手机号码必须有 8 位数字,中国 11 位数字等。目前我正在使用反应形式格式的 ng4-intl-phone 以允许用户输入他们的手机号码。
验证应该根据每个国家出现,而不是对国际 phone 号码的一般检查,比如号码是 3 到 14 位数字(这是我之前使用的)。
感谢您的帮助!
更新
我暂时用https://www.npmjs.com/package/ngx-international-phone-number代替。如果有需要的人可以参考,我还是会在下面留下答案!
我在我的 angular 6 项目中使用了 libphonenumber-js,它工作得很好。
这是我的自定义解决方案。它适用于我的解决方案。
请为您的项目安装 intl-tel-input
npm i intl-tel-input --save
然后创建一个IntlTelInputComponent
组件如下。
国际电话input.component.ts
import {
AfterViewInit, Component, ElementRef, EventEmitter, Input, Output, ViewChild, forwardRef, Renderer
} from '@angular/core';
import 'intl-tel-input';
import * as jQuery from 'jquery';
import { NG_VALUE_ACCESSOR, ControlValueAccessor, } from '@angular/forms';
export interface ITimeInputFieldChanged {
value: string;
extension: string;
numberType: string,
valid: boolean;
validationError: any
}
export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => IntlTelInputComponent),
multi: true
};
const noop = () => {
};
@Component({
selector: 'intl-tel-input',
templateUrl: './intl-tel-input.component.html',
styleUrls: ['./intl-tel-input.component.scss'],
providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class IntlTelInputComponent implements ControlValueAccessor {
@Input() fullValue: string;
@Output() fullValueChange = new EventEmitter<ITimeInputFieldChanged>();
@Input() id: string;
@Input() intlOptions = {
initialCountry: 'no',
formatOnDisplay: true,
separateDialCode: true,
onlyCountries: ['no', 'be']
};
@Input() value: string;
@Output() valueChange = new EventEmitter<string>();
@Output() valueBlur = new EventEmitter<string>();
@Output() valueFocus = new EventEmitter();
@ViewChild('intlInput') intlInput: ElementRef;
private extension: string;
private onTouchedCallback: () => void = noop;
private onChangeCallback: (_: any) => void = noop;
constructor(
private _renderer: Renderer) { }
onInputChange(value: string) {
const intlInput = jQuery(this.intlInput.nativeElement)
this.value = value;
this.valueChange.emit(value);
this.fullValue = intlInput.intlTelInput('getNumber');
this.extension = intlInput.intlTelInput('getSelectedCountryData').dialCode;
const validationErrorCode = intlInput.intlTelInput('getValidationError');
let validationMessage = 'VALID';
switch (validationErrorCode) {
case 1:
validationMessage = 'INVALID_COUNTRY_CODE'
break;
case 2:
validationMessage = 'TOO_SHORT'
break;
case 3:
validationMessage = 'TOO_LONG'
break;
case 4:
validationMessage = 'NOT_A_NUMBER'
break;
case 5:
break;
default:
validationMessage = 'VALID'
break;
}
this.fullValueChange.emit({
value: value,
extension: this.extension,
numberType: intlInput.intlTelInput('getNumberType'),
valid: intlInput.intlTelInput('isValidNumber'),
validationError: validationMessage
});
// this.writeValue(this.fullValue);
}
onBlur(value: string) {
this.valueBlur.emit(value);
}
onFocus() {
this.valueFocus.emit();
}
writeValue(value: any): void {
if (value && (value !== this.value)) {
this.fullValue = value;
setTimeout(() => {
const phoneInput = jQuery(`input#${this.id}`);
phoneInput.intlTelInput('setNumber', this.fullValue);
}, 100);
}
}
registerOnChange(fn: any): void {
this.onChangeCallback = fn;
}
registerOnTouched(fn: () => any): void { this.onTouchedCallback = fn; }
setDisabledState?(isDisabled: boolean): void {
throw new Error('Method not implemented.');
}
}
国际电话input.component.html
<input #intlInput class="form-control"
[appIntlTelInput]="intlOptions"
[id]="id"
[ngModel]="value"
(ngModelChange)="onInputChange($event)"
(blur)="onBlur($event)"
(focus)="onFocus()"
>
国际电话input.component.scss
:host /deep/.intl-tel-input{
display: block;
.country-list{
overflow-y: auto;
}
}
国际电话input.directive.ts
import { Directive, ElementRef, Input, OnInit } from '@angular/core';
import 'intl-tel-input';
import * as jQuery from 'jquery';
@Directive({
selector: '[appIntlTelInput]'
})
export class IntlTelInputDirective implements OnInit {
@Input('appIntlTelInput') appIntlTelInput: any;
constructor(private el: ElementRef) { }
ngOnInit() {
// jQuery.fn.intlTelInput.loadUtils('https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.12/js/utils.js');
// jQuery.fn.intlTelInput.loadUtils('/intl-tel-input/build/js/utils.js');
jQuery.fn.intlTelInput.loadUtils('assets/js/utils.js');
jQuery(this.el.nativeElement).intlTelInput(this.appIntlTelInput);
}
}
表单内的用法
<intl-tel-input formControlName="Mobile" ></intl-tel-input>
希望这能解决您的问题。它可以根据需要验证任何国际手机号码。
是否有 library/service class 可用于单独验证国际手机号码?例如。新加坡手机号码必须有 8 位数字,中国 11 位数字等。目前我正在使用反应形式格式的 ng4-intl-phone 以允许用户输入他们的手机号码。
验证应该根据每个国家出现,而不是对国际 phone 号码的一般检查,比如号码是 3 到 14 位数字(这是我之前使用的)。
感谢您的帮助!
更新
我暂时用https://www.npmjs.com/package/ngx-international-phone-number代替。如果有需要的人可以参考,我还是会在下面留下答案!
我在我的 angular 6 项目中使用了 libphonenumber-js,它工作得很好。
这是我的自定义解决方案。它适用于我的解决方案。
请为您的项目安装 intl-tel-input
npm i intl-tel-input --save
然后创建一个IntlTelInputComponent
组件如下。
国际电话input.component.ts
import {
AfterViewInit, Component, ElementRef, EventEmitter, Input, Output, ViewChild, forwardRef, Renderer
} from '@angular/core';
import 'intl-tel-input';
import * as jQuery from 'jquery';
import { NG_VALUE_ACCESSOR, ControlValueAccessor, } from '@angular/forms';
export interface ITimeInputFieldChanged {
value: string;
extension: string;
numberType: string,
valid: boolean;
validationError: any
}
export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => IntlTelInputComponent),
multi: true
};
const noop = () => {
};
@Component({
selector: 'intl-tel-input',
templateUrl: './intl-tel-input.component.html',
styleUrls: ['./intl-tel-input.component.scss'],
providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR]
})
export class IntlTelInputComponent implements ControlValueAccessor {
@Input() fullValue: string;
@Output() fullValueChange = new EventEmitter<ITimeInputFieldChanged>();
@Input() id: string;
@Input() intlOptions = {
initialCountry: 'no',
formatOnDisplay: true,
separateDialCode: true,
onlyCountries: ['no', 'be']
};
@Input() value: string;
@Output() valueChange = new EventEmitter<string>();
@Output() valueBlur = new EventEmitter<string>();
@Output() valueFocus = new EventEmitter();
@ViewChild('intlInput') intlInput: ElementRef;
private extension: string;
private onTouchedCallback: () => void = noop;
private onChangeCallback: (_: any) => void = noop;
constructor(
private _renderer: Renderer) { }
onInputChange(value: string) {
const intlInput = jQuery(this.intlInput.nativeElement)
this.value = value;
this.valueChange.emit(value);
this.fullValue = intlInput.intlTelInput('getNumber');
this.extension = intlInput.intlTelInput('getSelectedCountryData').dialCode;
const validationErrorCode = intlInput.intlTelInput('getValidationError');
let validationMessage = 'VALID';
switch (validationErrorCode) {
case 1:
validationMessage = 'INVALID_COUNTRY_CODE'
break;
case 2:
validationMessage = 'TOO_SHORT'
break;
case 3:
validationMessage = 'TOO_LONG'
break;
case 4:
validationMessage = 'NOT_A_NUMBER'
break;
case 5:
break;
default:
validationMessage = 'VALID'
break;
}
this.fullValueChange.emit({
value: value,
extension: this.extension,
numberType: intlInput.intlTelInput('getNumberType'),
valid: intlInput.intlTelInput('isValidNumber'),
validationError: validationMessage
});
// this.writeValue(this.fullValue);
}
onBlur(value: string) {
this.valueBlur.emit(value);
}
onFocus() {
this.valueFocus.emit();
}
writeValue(value: any): void {
if (value && (value !== this.value)) {
this.fullValue = value;
setTimeout(() => {
const phoneInput = jQuery(`input#${this.id}`);
phoneInput.intlTelInput('setNumber', this.fullValue);
}, 100);
}
}
registerOnChange(fn: any): void {
this.onChangeCallback = fn;
}
registerOnTouched(fn: () => any): void { this.onTouchedCallback = fn; }
setDisabledState?(isDisabled: boolean): void {
throw new Error('Method not implemented.');
}
}
国际电话input.component.html
<input #intlInput class="form-control"
[appIntlTelInput]="intlOptions"
[id]="id"
[ngModel]="value"
(ngModelChange)="onInputChange($event)"
(blur)="onBlur($event)"
(focus)="onFocus()"
>
国际电话input.component.scss
:host /deep/.intl-tel-input{
display: block;
.country-list{
overflow-y: auto;
}
}
国际电话input.directive.ts
import { Directive, ElementRef, Input, OnInit } from '@angular/core';
import 'intl-tel-input';
import * as jQuery from 'jquery';
@Directive({
selector: '[appIntlTelInput]'
})
export class IntlTelInputDirective implements OnInit {
@Input('appIntlTelInput') appIntlTelInput: any;
constructor(private el: ElementRef) { }
ngOnInit() {
// jQuery.fn.intlTelInput.loadUtils('https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/11.0.12/js/utils.js');
// jQuery.fn.intlTelInput.loadUtils('/intl-tel-input/build/js/utils.js');
jQuery.fn.intlTelInput.loadUtils('assets/js/utils.js');
jQuery(this.el.nativeElement).intlTelInput(this.appIntlTelInput);
}
}
表单内的用法
<intl-tel-input formControlName="Mobile" ></intl-tel-input>
希望这能解决您的问题。它可以根据需要验证任何国际手机号码。