用逻辑复制表格

专家实验室

我创建了一个动态表单字段,可以通过按钮DelBtn()的回调函数添加和删除该动态表单字段,以删除项目和AddBtn()添加项目

每个表单字段都有一个value输入

我也有一个totalval领域。我希望所有value字段中的值总和不超过totalval如果是这样,我们将显示一条错误消息,如果值相等,则使reason表单字段出现。

例:

如果我有totalValue = 100现在说我有我的第一个表格字段value = 90

然后,我复制表单,value = 10然后在下一个字段集中reason显示字段,因为90 + 10 = 100由于totalValue已经达到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

注意:如果您不理解该问题,请随时在评论中问我,我正在使用angular(typescript)

欧文·凯尔文(Owen Kelvin)

用basic很难做到这一点Javascript下面的方法使用ReactiveForm方法

我们遵循以下步骤

  • 将添加ReactiveFormsModuleimports模块数组
@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] });

我们添加了一个cusom验证器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;
  }
  • 我们还需要修改功能以从formArray添加和删除项目
  DelBtn = delIndex => this.formsArray.controls.splice(delIndex, 1);
  AddBtn = () => this.formsArray.push(this.fb.control(""));
  • 最后,我们可以formGroup在html中实现
<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我们将拥有一个类似于aformGroup的值

  {
    totalVal: 100,
    formsArray: ['50', '20', '10'],
    reason: ''
  }

在上面的代码中,我们简单地从formGroup使用control.get('totalVal').value相同的提取100 formArray由于formArrayvalue将是一个数组,因此我们可以使用reduce函数对其求和。.最后,我们对此进行比较,如果匹配则返回null,如果Object不匹配则返回an

通过以上方法,角度反应式表格将valid根据用户提供的内容更新表格状态的值因此,我们可以利用此valid状态来更新UI

arrayFullyFilled()

get arrayFullyFilled() { 
  return !this.formsArray.controls.some(item => item.errors) 
}

上面的代码尝试查找用户是否已填充数组中的所有输入。在我们的数组中,我们获取所有控件,检查其中一些控件是否有错误,如果有错误,则返回false,否则返回true。考虑到我formGroup使用验证时已使之formControls成为可能requiredValidators.required

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章