#angular #regex #input #angular-validation #input-mask
#angular #регулярное выражение #ввод #angular-проверка #ввод-маска
Вопрос:
У меня проблема с использованием маски и регулярного выражения на входе.
Это ввод:
<mat-form-field
>
<mat-label >HH:mm:ss:SSS</mat-label>
<input
matInput
[formControlName]="duration?.id"
[id]="duration?.id"
[name]="duration?.id"
placeholder="HH:mm:ss:SSS"
appDurationMask
type="text"
/>
<mat-error *ngIf="!isInvalidPattern"
>{{ duration?.label }} is required</mat-error
>
<mat-error *ngIf="isInvalidPattern"
>invalid pattern must be HH:mm:ss:SSS</mat-error
>
</mat-form-field>
Функция isInvalidPattern выглядит так:
get isInvalidPattern() {
return this.form.controls[this.data.id].errors
? this.form.controls[this.data.id].errors.pattern
: false;
}
Директива mask выглядит так:
export class DurationMaskDirective {
constructor(public ngControl: NgControl) {}
@HostListener('ngModelChange', ['$event'])
onModelChange(event) {
this.onInputChange(event, false);
}
@HostListener('keydown.backspace', ['$event'])
keydownBackspace(event) {
this.onInputChange(event.target.value, true);
}
onInputChange(event, backspace) {
let newVal = event.replace(/D/g, '');
if (backspace amp;amp; newVal.length <= 6) {
newVal = newVal.substring(0, newVal.length - 1);
}
if (newVal.length === 0) {
newVal = '';
} else if (newVal.length <= 2) {
newVal = newVal.replace(/^(d{0,2})/, '$1');
} else if (newVal.length <= 4) {
newVal = newVal.replace(/^(d{0,2})(d{0,2})/, '$1:$2');
} else if (newVal.length <= 6) {
newVal = newVal.replace(/^(d{0,2})(d{0,2})(d{0,2})/, '$1:$2:$3');
} else if (newVal.length <= 9) {
newVal = newVal.replace(
/^(d{0,2})(d{0,2})(d{0,2})(d{0,3})/,
'$1:$2:$3:$4'
);
} else {
newVal = newVal.substring(0, 9);
newVal = newVal.replace(
/^(d{0,2})(d{0,2})(d{0,2})(d{0,3})/,
'$1:$2:$3:$4'
);
}
this.ngControl.valueAccessor.writeValue(newVal);
this.ngControl.valueAccessor.writeValue(newVal);
}
Проблема довольно проста: когда я записываю что-то во входных данных, что не соответствует шаблону, даже если ничего не видно, для invalidpattern устанавливается значение true .
Если я написал одно число, а затем удалил его, для invalidpattern устанавливается значение true. Если я хорошо написал свой шаблон, то добавьте 1 цифру или букву или что-нибудь еще, даже если единственное, что видно, это хороший шаблон, invalidpattern имеет значение true . Когда я отлаживаю, я вижу, что даже если я удаляю (используя backspace), он все равно сохраняет в памяти последнее число, даже если пользователю ничего не видно.
Например, если на входе я написал 1, а затем использовал backspace, пользователь ничего не видит во входных данных, но значение this.form.controls[this.metadata.id].value
равно 1.
Если я напишу 11:11:11:111, затем добавьте 1 в конце, даже если входные данные показывают 11:11:11:111, значение this.form.controls[this.metadata.id].value
равно 11:11:11:1111.
Что я могу сделать, чтобы решить эту проблему?
Редактировать
Комментарии:
1. Если вы предоставите ссылку на stackblitz или что-то подобное, это поможет.
2. я добавил ссылку для stackblitz в edit