描述我有一个带有输入字段的表单,该字段应该包含1到4个字符的代码。它应该只包含字母,最好只包含大写字母。
我编写了函数keepCodeFormatted()
,以便在用户键入时更正输入。但我迷失的是,这个值似乎在不同的地方,并不是所有的更新都一样。我做错了什么
有关示例,请参见html
部分中的输出1,2,3。通常,输出1包含我想要的内容,输出2和3包含前一步的内容或错误内容(数字(。
示例
我输入小写的"d">
- 输出1:D
- 输出2:d
- 输出3:d
然后我输入一个数字"3">
- 输出1:D
- 输出2:D3
- 输出3:D3
然后我输入一个大写的"T"(这里一切都按预期进行
- 输出1:DT
- 输出2:DT
- 输出3:DT
然后我输入一个'<'符号
- 输出1:DT
- 输出2:DT<
- 输出3:DT<
结果问题 使用
- 输出1:DT
- 输出2:DT<
- 输出3:DT<
请记住,用户只能看到Output 1
->输入看起来是有效的,但按钮是不可点击的,用户并没有意识到输入实际上处于无效状态。(与数字相同,而不是符号(
带输出1:DTM输出2:DTm输出3:DTm可以提交表单,但提交的值是DTm而不是DTm。(请记住,大写字母是首选(因此在onSubmit方法中的某个位置使用了.toUpperCase((。。。但这不应该是必需的。
尝试过我尝试过更新this.myFormGroup.value.code
,但没有改善。我尝试更新this.myFormGroup.controls['code']
,但这是只读的。我试过this.myFormGroup.controls['code'].updateValueAndValidity();
,但在这种情况下,它并没有起到任何作用。我尝试使用keydown
,但这使情况变得更糟(例如,阻止[enter]密钥提交。
myForm(html(
<form #myForm="ngForm" [formGroup]="myFormGroup" (ngSubmit)="onSubmit()">
<div class="input-group w-25">
<input #code class="form-control" type="text" maxlength="4" size="4" formControlName="code" (keyup)="code.value = keepCodeFormatted(code.value)" />
<button [disabled]="myFormGroup.invalid" class="btn btn-outline-primary" type="submit" id="button-whatever">Submit</button>
</div>
</form>
<p>Output 1:{{code.value}}</p>
<p>Output 2:{{myFormGroup .value.code}}</p>
<p>Output 3:{{myFormGroup .controls['code'].value}}</p>
组件与我的form.component.ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, Validators } from '@angular/forms';
import { ServiceThatUsesCode } from '../../service-that-uses-code.service';
@Component({
selector : 'component-with-my-form',
templateUrl: './component-with-my-form.component.html',
styles : ['button[disabled] {color:grey;border-color:grey}']})
export class ComponentWithMyForm implements OnInit {
myFormGroup = this.formBuilder.group({
code: new FormControl('', [
Validators.required,
Validators.maxLength(5),
Validators.pattern(/^[A-Za-z]+$/) //I'd be tempted to remove ^and +$ and a-z but I'm very bad at regular expressions...
]),
});
constructor(private serviceThatUsesCode: ServiceThatUsesCode, private formBuilder: FormBuilder) { }
ngOnInit(): void {}
onSubmit(): void {
let code: string | null | undefined = this.myFormGroup.value.code;
if (code) {
this.serviceThatUsesCode.useCode(code.toUpperCase());
this.myFormGroup.reset();
}
}
keepCodeFormatted(code: string) {
let formattedValue: string = code.replace(/[^A-Za-z]/g, '').toUpperCase();
this.myFormGroup.value.code = formattedValue;
//this.myFormGroup.controls['code'] = formattedValue; // Can't because left is read only
this.myFormGroup.controls['code'].updateValueAndValidity();
return formattedValue;
}
}
如果在这里找到:如何自动将文本框设置为大写?有一种方法可以在基本的JavaScript/HTML中做到这一点。
所以我更换了
<input #code class="form-control" type="text" maxlength="4" size="4" formControlName="code" (keyup)="code.value = keepCodeFormatted(code.value)" />
带
<input #code class="form-control" type="text" maxlength="4" size="4" formControlName="code" oninput="this.value = this.value.replace(/[^A-Za-z]/g, '').toUpperCase()" />
或者
<input #code class="form-control" type="text" maxlength="4" size="4" formControlName="code" oninput="this.value = this.value.toUpperCase().replace(/[^A-Z]/g, '')" />