掩码输入值日期格式 Angular

Mask Input Value Date Format Angular

我想屏蔽我的 input 值,基本上我有一个信用卡到期日输入字段并想以 mm/yy 格式屏蔽它,这就是我试过的方法 :

输入-mask.directive.ts

import { Directive, HostListener } from '@angular/core';
import { NgControl } from '@angular/forms';

@Directive({
  selector: '[formControlName][appInputMask]',
})
export class InputMaskDirective {

  @HostListener('input', ['$event'])
  onKeyDown(event: KeyboardEvent) {
    const input = event.target as HTMLInputElement;

    const trimmed = input.value.replace(/\s+/g, '').slice(0, 4);
    if (trimmed.length > 3) {
      return (input.value = `${trimmed.slice(0, 2)}/${trimmed.slice(2)}`);
    }
  }
}

我得到了预期的输出,但问题是在输入字段上使用退格键时,它搞砸了,这是我在 stackblitz 上的演示,如何解决这个问题?还是有更好的输入掩码方法?

使用 ngx-mask 只需为日期、卡片等提供图案,即可让您的工作变得轻松。

<input type='text' mask='99/99' >

这里是stackblitz demo

问题

  1. HTMLInput 元素的最大长度应为 5,否则一旦您以编程方式在其中添加斜杠,它就不允许用户添加 4 位数字。

  2. 同样的问题存在于const trimmed = input.value.replace(/\s+/g, '').slice(0,4); 如果它包含斜杠,切片应该在 5 而不是 4 处结束。

  3. return语句中

    return (input.value = `${trimmed.slice(0, 2)}/${trimmed.slice(2)}`);
    

如果添加一次斜线,${trimmed.slice(2) 将 return /\d{1,2}。所以你需要避免斜线并从 3.

开始

解决方案

将最大长度从 4 更改为 5

 <input ... maxlength="5">

现在,输入-mask.directive.ts需要一些改变

改变

const trimmed = input.value.replace(/\s+/g, '').slice(0,4);

const trimmed = input.value.replace(/\s+/g, '').slice(0, input.value.indexOf('/')==-1?4:5);

因为加上/,长度会变成5.

Don't use .slice(0) because it allows a user to paste 5 digits and when you add a slash, it'll become 6. So the date will look like 11/111 instead of 11/11

改变

return (input.value = `${trimmed.slice(0, 2)}/${trimmed.slice(2)}`);

return (input.value = `${trimmed.slice(0, 2)}/${trimmed.slice(trimmed.indexOf('/')==-1?2:3)}`);

这就是您的代码混乱的地方。如果它包含斜杠,那么你应该从 3 开始切片。否则从 2 开始切片。

输入掩码指令中 HostListener 的最终代码

@HostListener('input', ['$event'])
onKeyDown(event: KeyboardEvent) {
  const input = event.target as HTMLInputElement;

  const trimmed = input.value.replace(/\s+/g, '').slice(0, input.value.indexOf('/')==-1?4:5);
  if (trimmed.length > 3) {
    return (input.value = `${trimmed.slice(0, 2)}/${trimmed.slice(trimmed.indexOf('/')==-1?2:3)}`);
  }
}

工作示例:stackblitz

使用下面的代码。 创建指令 .ts 文件并添加以下代码

import { Directive, HostListener } from '@angular/core';
import { NgControl } from '@angular/forms';

@Directive({
    selector: '[formControlName][inputDateMask]',
})
export class InputMaskDirective {
    constructor(public ngControl: NgControl) { }

    @HostListener('ngModelChange', ['$event'])
    onModelChange(event: any) {
        this.onInputChange(event, false);
    }

    @HostListener('keydown.backspace', ['$event'])
    keydownBackspace(event: any) {
        this.onInputChange(event.target.value, true);
    }

    onInputChange(event: any, backspace: any) {
        let newDate = '';
     
        let month: string = "";
        let day: string = "";
        let year: string = "";

        if (event)
            newDate = event.replace(/\D/g, '');

        if (backspace) {
            newDate = newDate.substring(0, newDate.length - 1);
        }
        if (newDate.length > 7) {

            if(newDate.match(/^[0-9]+$/) ? true : false)
            month = newDate.substring(0, 2);
            day = newDate.substring(2, 4);
            year = newDate.substring(4, 8);
            newDate = (`${month}/${day}/${year}`);

            this.ngControl?.valueAccessor?.writeValue(newDate);
        }
    }
}

然后在 app.module.ts 文件中声明指令

declarations: [
 InputMaskDirective
],

exports: [
  InputMaskDirective
]

像这样使用指令

<input matInput placeholder="MM/DD/YYYY" [maxlength]="10" inputDateMask formControlName="dateOfBirth" />

希望对您有所帮助,谢谢