我已经提到链接:Input mask fields in Angular2 forms我可以屏蔽输入字段,如:(123)456-7890。
请在下面找到更新的代码:
指令TS档案:
@Directive({
selector: '[appPhoneMasking]',
host: {
'(ngModelChange)': 'onInputChange($event)',
'(keydown.backspace)': 'onInputChange($event.target.value, true)'
}
})
export class PhoneMaskingDirective {
constructor(public model: NgControl) {}
onInputChange(event, backspace) {
// remove all mask characters (keep only numeric)
var newVal = event.replace(/\D/g, '');
if (backspace) {
newVal = newVal.substring(0, newVal.length - 1);
}
// don't show braces for empty value
if (newVal.length == 0) {
newVal = '';
}
// don't show braces for empty groups at the end
else if (newVal.length <= 3) {
newVal = newVal.replace(/^(\d{0,3})/, '($1)');
} else if (newVal.length <= 6) {
newVal = newVal.replace(/^(\d{0,3})(\d{0,3})/, '($1) $2-');
} else {
newVal = newVal.replace(/^(\d{0,3})(\d{0,3})(.*)/, '($1) $2-$3');
}
if(newVal.length > 14) {
newVal = newVal.slice(0, 14);
}
// set the new value
this.model.valueAccessor.writeValue(newVal);
}
}
和HTML文件:
<form [formGroup]="addUser" (ngSubmit)="submitUser()">
<input type="text" class="form-control" formControlName="user_phone" appPhoneMasking>
</form>
组件文件:
this.addUser= this._formBuilder.group({
user_phone: new FormControl('', [Validators.maxLength(14)]),
});
我有两个问题,我试图解决但没有成功。这些是:
请告诉我如何解决这些问题。
答案 0 :(得分:1)
当我按退格键时,将从字符串中删除两个字符。
您不需要将if用作退格键,则退格事件有效,然后再删除一个字符。
答案 1 :(得分:0)
将您的 if(退格)条件稍微更改为:
if (backspace && (event[event.length - 1] == "-" || event[event.length - 1] == ")")) {...}
此外,请确保将事件参数设置为类型字符串以访问长度属性。
如果没有添加条件,退格键总是会删除 2 个字符。 但是,当您完全删除 if 语句时。每当您到达破折号或右括号时,它就会卡住。这是因为默认的退格事件会删除该格式字符,但由于函数的格式行为,它会在最后重新添加。
更新: 如果您希望光标位置保持不变而不是跳到最后。你只需要在构造函数中添加一个私有的 ElementRef 属性,并在你的函数开始时调整一些东西:
constructor(
private el: ElementRef,
public model: NgControl,
) { }
onInputChange(event: string, backspace) {
// remove all mask characters (keep only numeric)
var newVal = event.replace(/\D/g, '');
let start = this.el.nativeElement.selectionStart;
if (backspace && (event[event.length - 1] == "-" || event[event.length - 1] == ")")) {
if (start == event.length) {
newVal = newVal.substring(0, newVal.length - 1);
}
else {
setTimeout(() => {
this.el.nativeElement.selectionStart = start - 1;
this.el.nativeElement.selectionEnd = start - 1;
});
}
}
else {
if (backspace) {
setTimeout(() => {
this.el.nativeElement.selectionStart = start - 1;
this.el.nativeElement.selectionEnd = start - 1;
});
}
else {
if (start != event.length) {
switch (start) {
case 5:
setTimeout(() => {
this.el.nativeElement.selectionStart = start + 2;
this.el.nativeElement.selectionEnd = start + 2;
});
break;
case 6:
setTimeout(() => {
this.el.nativeElement.selectionStart = start + 1;
this.el.nativeElement.selectionEnd = start + 1;
});
break;
case 10:
setTimeout(() => {
this.el.nativeElement.selectionStart = start + 1;
this.el.nativeElement.selectionEnd = start + 1;
});
break;
default:
setTimeout(() => {
this.el.nativeElement.selectionStart = start;
this.el.nativeElement.selectionEnd = start;
});
break;
}
}
}
}
....
}
注意:在 setTimeout() 中设置光标位置很重要,以便实际设置。
答案 2 :(得分:0)
<div class="row">
<div class="col s4">
<mat-form-field appearance="outline" class="common-form-field-width">
<mat-label>{{'MOBILE' | translate: lang}}</mat-label>
<input appTrim required matInput [placeholder]="patternDetails?.phoneNumberFormat" autocomplete="off" formControlName="userMobile">
<mat-hint *ngIf="(CustomerForm.controls['userMobile'].invalid && (CustomerForm.controls['userMobile'].dirty || CustomerForm.controls['userMobile'].touched))">
<mat-error *ngIf="CustomerForm.controls['userMobile'].errors.required">
{{ 'REQUIRED' | translate:lang }}
</mat-error>
<mat-error *ngIf="CustomerForm.controls['userMobile'].errors.pattern">
{{ 'ERROR_INVALID_MOBILE' | translate:lang }} {{'LABEL_EX' | translate: lang}} {{patternDetails?.phoneNumberFormat}})
</mat-error>
<mat-error *ngIf="CustomerForm.controls['userMobile'].errors.minlength">
{{ 'ERROR_MOBILE_DIGITS' | translate:lang }}{{customerRules.MOBILE_MIN_LENGTH}}{{ 'DIGITS' | translate:lang}}
</mat-error>
</mat-hint>
</mat-form-field>
</div>
userMobile: ['', [Validators.required, Validators.pattern(this.customerRules.MOBILE_PATTERN),
Validators.minLength(this.customerRules.MOBILE_MIN_LENGTH)]]
export const CUSTOMER_RULE = () => {
return {
'NAME_PATTERN': `[${getUniCode()}]+(\\s[${getUniCode()}]+){0,}?`,
'FIRST_NAME': `[${getUniCode()}0-9]+(\\s[${getUniCode()}0-9]+){0,}?`,
'FIRST_NAME_MIN_LENGTH': 3,
'FIRST_NAME_MAX_LENGTH': 100,
'LAST_NAME': `[${getUniCode()}0-9]+(\\s[${getUniCode()}0-9]+){0,}?`,
'LAST_NAME_MIN_LENGTH': 1,
'LAST_NAME_MAX_LENGTH': 100,
'MOBILE_PATTERN': '[+0-9]*',
'MOBILE_MIN_LENGTH': 4,
'MOBILE_MAX_LENGTH': 13,
'ADDRESS_MIN_LENGTH': 3,
'ADDRESS_MAX_LENGTH': 250,
'ZIPCODE': '[0-9]*',
'ZIPCODE_MIN_LENGTH': 4,
'ZIPCODE_MAX_LENGTH': 10,
'PASSWORD_PATTERN': '^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[`~#^()_+={}<>";:|[/,.$@$!%*?&-])[A-Za-z0-9`~#^()_+={}<>":;|[/,.$@$!%*?&-]{6,20}',
'EMAIL_PATTERN': '^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$',
'RESOLUTION': {
'RESOLUTION_WIDTH': 0,
'RESOLUTION_HEIGHT': 0
}
};
};