Skip to content Skip to sidebar Skip to footer

Angular Material Matchiplist - How To Use It On A Dynamic Formarray?

StackBlitz Here is my FormArray (variants): this.productGroup = this.fb.group({ name: '', variants: this.fb.array([ this.fb.group({ type: '', options

Solution 1:

I'm not sure the dom reference variable #chiplist is the issue. It looks like the matChipList is backed by the typesOptions array, but you only have one array. So every time you add a matChipList component it is still being backed by the same array as all the others. You need to have an array of typesOptions, an array of arrays. Then when you addItem, you also push a new sub array to typesOptions (and similarly remove one for removeItem).

I haven't coded this up, just a suggestion from looking at the code.

Edit - coded up a solution based on James's stackblitz.

https://stackblitz.com/edit/angular-3od6rd-jkidxf

Note I haven't looked in detail at how the delete variant holds together, ideally I'd probably like to use a key/value pair to track the variant options using the dom input element id as the key (which is in the MatChipInputEvent), instead of relying on the outer loop index.

Some code from the stackblitz:

export classChipsOverviewExample{
  productGroup: FormGroup;
  variantsArray: FormArray;
  typesOptionsArray: string[][] = [];
  readonly separatorKeysCodes: number[] = [ENTER, COMMA];

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.productGroup = this.fb.group({
      name: '',
      variants: this.fb.array([
        this.fb.group({
          type: '',
          options: ''
        })
      ]),
    });
    this.typesOptionsArray.push([]);
  }

  saveProduct(form: FormGroup) {
    console.log(form);
  }

  // Add new item to FormArray
  addItem(): void {
    this.variantsArray = this.productGroup.get('variants') as FormArray;
    this.variantsArray.push(this.fb.group({
      type: '',
      options: ''
    }));

    this.typesOptionsArray.push([]);
  }

  removeItem(index: number) {
    this.variantsArray.removeAt(index);
  }

  addOpt(event: MatChipInputEvent, index: number): void {
    const input = event.input;
    const value = event.value;
    // Add our fruitif ((value || '').trim()) {
      this.typesOptionsArray[index].push(value.trim());

    }
    // Reset the input valueif (input) {
      input.value = '';
    }
  }

  removeOpt(opt: string, index: number): void {
    const optIndex = this.typesOptionsArray[index].indexOf(opt);
    if (optIndex >= 0) {
      this.typesOptionsArray[index].splice(optIndex, 1);
    }
  }
}

Solution 2:

try to make the formGroup as a new component and input formGroup to it(not formGroupName).

<divformArrayName="variants" *ngFor="let item of productGroup.controls['variants'].controls; let i = index;"><variant [varientGroup]="item"><varient><divclass="row"><ahref="javascript:" (click)="addItem()"> Add Variants </a><ahref="javascript:" (click)="removeItem(i)" *ngIf="i > 0"> Remove Variants </a></div></div>

varient component.html

<div [formGroup]="varientGroup"><divclass="row"><mat-form-fieldclass="col-12"><inputformControlName="type"></mat-form-field></div><divclass="row"><mat-form-fieldclass="col-12"><mat-chip-list #chipList><mat-chip *ngFor="let opt of typesOptions" [selectable]="true"
                [removable]="true" (removed)="removeOpt(opt)">
          {{opt}}
          <mat-iconmatChipRemove>cancel</mat-icon></mat-chip><inputplaceholder="Conjunto de opções deste Tipo"
              [matChipInputFor]="chipList"
              [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
              [matChipInputAddOnBlur]="true"
              (matChipInputTokenEnd)="addOpt($event)"></mat-chip-list></mat-form-field></div></div>

in varient.component.ts

@Input()varientGroup: FormGroup

Post a Comment for "Angular Material Matchiplist - How To Use It On A Dynamic Formarray?"