Home > Blockchain >  How to check if new control is added in NgForm?
How to check if new control is added in NgForm?

Time:06-09

I'm new to the NgForm. So here's the code & below the scenario...

  1. I have an application where use has to enter multiple server paths.
  2. All the paths are stored in a list. UI populates all the paths using *ngFor. By default the list is initialized with a dumb entry
public list: any[];
this.list = [
  {
    path: '',
    port: null,
  },
];

So this is how the code looks like

<form #serverForm="ngForm">
  <div *ngFor="let item of list; let i = index">
    <input
      type="text"
      name="path{{ i }}"
      id="path{{ i }}"
      [value]="item.path"
      [(ngModel)]="list[i].path"
    />
  </div>
</form>
  1. Each path is a text field & each field is a control
  2. Control gets their name by name attribute name="path{{ i }}" & each control has a pattern validator attached to it
    path: new FormControl('', [Validators.required, Validators.pattern(this.pattern)])
  3. Pattern can be of multiple types. E.g., here user can select one of the 2 patterns from UI
<div>
  <label> Pattern Type </label><br />
  <input type="radio" name="patternType" (change)="setPattern(1)" />String
  <input type="radio" name="patternType" (change)="setPattern(2)" />Numbers
</div>

setPattern(v: number) {
    if (v === 1) {
      this.pattern = /[a-z] /;
    } else if (v === 2) {
      this.pattern = /[A-Z] /;
    }
    // setting formcontrol pattern validator
    this.serverForm.controls['path0']?.addValidators(
      Validators.pattern(this.pattern)
    );
  }
  1. As you can see, the last line is to attach a validator pattern to the first control path0
  2. User tries entering new path by clicking on Add new entry button. This button has a method associated with it which will add a new field.<button (click)="addNewEntry()">Add new path</button> adds a new dumb entry to the list & a new field comes up in the UI.
public addNewEntry() {
    this.list.push({
      path: '',
      port: null,
    });
  }
  1. When *ngFor iterates over the list, name attribute which is unique because of the index, a new control gets automatically added to the NgForm serverForm

So what is the issue?

  1. Most important, how to detect dynamically that a new control is available in the form and I should attach a validator to it? I don't want to even hardcode the path0 in setPattern() in point 5
  2. addNewEntry() has no clue that a new control is added which makes difficult to add pattern validator in this.pattern. Because addNewEntry() executed before this.serverForm.valueChanges.subscribe

How to resolve this? Basically I want to dynamically attach a pattern validator to the newly generated control inside the NgForm

Also here is the code for the same.

CodePudding user response:

I would argue that you're taking the wrong approach. It is much easier to achieve the result you want with Reactive forms vs template-driven forms as you have attempted to do.

What is great about reactive forms is that they have their own built-in arrays, and you can push new form groups into them with whatever validation you want, like so:

public addNewEntry() {
    const pattern = this.patternValue === '1' ? /[a-z] / : /[0-9] /;

    this.serverArray.push(
      this.fb.group({
        path: [null, [Validators.pattern(pattern)]],
        port: '',
      })
    );
  }

StackBlitz here. I changed the validator regex because the other regex was for capital letters, not numbers.

  • Related