我已经创建了一个动态表单字段,通过按钮上的回调函数添加和删除该字段,DelBtn()删除项,AddBtn()添加项。
每个表单字段都有一个value输入。
我还有一个totalval字段。我期望所有value字段中的值之和不超过totalval。如果是这样的话,我们将显示一条错误消息,如果值等于,则会显示reason表单字段。
示例:
如果我有totalValue = 100。现在假设我有我的第一个表单字段value = 90。
然后我复制表单,在下一个字段中设置value = 10,那么reason字段应该会出现,因为90 + 10 = 100。当到达totalValue reason 时,应出现reason表单字段,并禁用添加按钮。
如果在第二次尝试中,如果用户试图输入大于10的值,则应该显示错误消息。
下面是我的当前代码
在我的TS文件里
ischecks: boolean = true;
formsArray = [""];
count: number = 0;
totalval: number = 100;
ngOnInit(): void {}
constructor() {}
clickCount(): void {
this.count++;
}
DelBtn = delIndex => this.formsArray.splice(delIndex, 1);
AddBtn = () => this.formsArray.push("");HTML
<h2> Form</h2>
<pre style="font-weight: bolder;font-family:verdana;margin-left: 35px;">Total Value:{{totalval}} </pre>
<div *ngFor="let i of formsArray; let a = index">
<div>
<form>
<table>
<div>
<label for="fname">Value:</label><br>
<input type="text" id="fname" name="fname" ><br>
<tr>
<td>
<button type="button" class="btn btn-outline-success"
style="border-radius:40px;margin-left: 50px" (click)="DelBtn(a)" ><span class="fa fa-plus"></span>Delete</button>
</td>
</tr>
<tr>
</div>
</table>
</form>
</div>
</div>
<div *ngIf=ischecks style="margin-left:35%">
<label for="fname">Reason:</label><br>
<input type="text" id="fname" name="fname" ><br>
</div>
<br>
<button type="button" class="btn btn-outline-success"
style="border-radius:40px;margin-left: 50px;margin-bottom: 30%;" (click)="AddBtn()" ><span class="fa fa-plus"></span>Add</button>https://stackblitz.com/edit/angular-ivy-3pbdwv?file=src%2Fapp%2Fapp.component.html
注意:如果你不明白这个问题,可以在评论中问我,我正在用角度写(打字稿)。
发布于 2020-11-11 18:37:20
这将很难用基本的Javascript来实现。下面的方法使用ReactiveForm方法
我们遵循以下步骤
ReactiveFormsModule添加到模块的imports数组中@NgModule({
imports:[ ReactiveFormsModule, ... ],FormBuilder类constructor(private fb: FormBuilder) {}myForm = this.fb.group({
totalVal: [100],
formsArray: this.fb.array([this.fb.control("", { validators: [Validators.required] })]),
reason: ["", [Validators.required]]
}, { validators: [sumMatches] });我们增加了一个缓冲验证器sumMatches。我们将使用此方法检查总价值之和是否匹配。
function sumMatches(control): ValidationErrors | undefined {
const totalVal = Number(control.get("totalVal").value);
const formsArrayTotal = control
.get("formsArray")
.value.reduce((a, b) => Number(a) + Number(b), 0);
if (formsArrayTotal !== totalVal) {
return {
sumMismatch: true
};
}
return;
}getter函数,从formGroup中提取属性。 get sumMismatch(): boolean {
return this.myForm.hasError('sumMismatch')
}
get arrayFullyFilled() {
return !this.formsArray.controls.some(item => item.errors)
}
get formsArray() {
return this.myForm.get("formsArray") as FormArray;
}
get totalVal() {
return this.myForm.get("totalVal") as FormControl;
} DelBtn = delIndex => this.formsArray.controls.splice(delIndex, 1);
AddBtn = () => this.formsArray.push(this.fb.control(""));formGroup。<h2> Form</h2>
<span class='totalVal'>Total Value:{{ totalVal.value }}</span>
<form [formGroup]='myForm'>
<ng-container formArrayName='formsArray'>
<table *ngFor="let item of formsArray.controls; let i = index">
<tr>
<td>
<div>
<label [attr.for]="'fname' + i">Value:</label><br>
<input type="number" [formControlName]="i" type="text" [id]="'fname' + i" name="fname" ><br>
</div>
</td>
<td>
<button type="button" class="btn btn-outline-success"
s (click)="DelBtn(i)" ><span class="fa fa-plus"></span>Delete</button></td>
<tr>
</table>
</ng-container>
<div *ngIf='!sumMismatch && arrayFullyFilled'>
<label for="fname">Reason:</label><br>
<input type="text" id="fname" name="fname" ><br>
</div>
<br>
<button type="button" class="btn btn-outline-success"
(click)="AddBtn()" ><span class="fa fa-plus"></span>Add</button>
<br>
<span class="error" *ngIf="sumMismatch && myForm.touched">Total Value Mismatch</span>
</form>我已经将css解压到自己的文件中。
.totalVal {
font-weight: bolder;
font-family: verdana;
}
.btn-outline-success {
border-radius: 40px;
margin-left: 50px;
}
.error {
color: red;
}编辑1-验证器是如何工作的?
为了理解这一点,我们看一下我们如何构建表单组。我们定义了一个在表单中生成值的结构。
{
totalVal: 100,
formsArray: [''],
reason: ''
}通过将表单组定义为this.fb.group({ ... }, {validators: [ sumMatches ] },具有上述值的表单组将传递给sumMatches函数
在sumMatches中,我们将有一个类似于具有以下值的formGroup
{
totalVal: 100,
formsArray: ['50', '20', '10'],
reason: ''
}在上面的文章中,我们简单地使用control.get('totalVal').value从control.get('totalVal').value中提取100到formArray。由于formArray值将是一个数组,所以我们可以使用reduce函数对此进行求和。最后,我们对此进行比较,如果匹配则返回null,如果不匹配则返回Object。
使用上述方法,角响应表单将根据用户提供的内容更新表单valid状态的值。因此,我们可以利用这个valid状态来更新UI
arrayFullyFilled()
get arrayFullyFilled() {
return !this.formsArray.controls.some(item => item.errors)
}上面的代码试图找出用户是否已将数组中的输入全部填充。在我们的数组中,我们获取所有控件,检查其中一些控件是否有错误,如果有错误,则返回false,否则返回true。这是可能的,因为在我的formGroup中,我使用Validators.required验证将formControls作为required来实现。
https://stackoverflow.com/questions/64790312
复制相似问题