屏蔽电话基于角度5的输入字段

时间:2018-03-05 12:58:31

标签: angular angular-directive

我已经提到链接: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)]),
});

我有两个问题,我试图解决但没有成功。这些是:

  1. 当我按退格键时,会从字符串中删除两个字符。
  2. 此外,我只想要14个字符的电话号码。只要输入15个字符,输入字段就会更新。但表格没有更新。我收到错误,表明我的表格无效。
  3. 请告诉我如何解决这些问题。

3 个答案:

答案 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
   }
  };
};

enter image description here

enter image description here

enter image description here