2
votes

I'm new in angular material design and I have a problem with mat-autocomplete for dynamic inputs. By default user see one input but when some value is selected than another input can be added and this is the tricky part - how to make that all those inputs will be using only one mat-autocomplete? Is it possible?

Below is code where I'm using mat-autocomplete. The addItem() function is adding another input which would be bind to the same mat-autocomplete. Should it be moved above ? And what about unique id? How can I solve this issue with multiple inputs connected to the same mat-autocomplete?

<div formArrayName="items" class="form-group"
    *ngFor="let item of items.controls; let i = index">

    <mat-form-field class="example-full-width">
        <input required type="text" placeholder="Item ID"
            matInput
            [formControlName]="i"
            [id]="i"
            [matAutocomplete]="auto">

        <mat-autocomplete #auto="matAutocomplete">
            <mat-option *ngFor="let option of filteredOptions | async"
                [value]="option.code"
                (click)="selectOption(option, i)">
                {{option.code}}
            </mat-option>
        </mat-autocomplete>

    </mat-form-field>

    <i *ngIf="i == 0 && selected" class="fa fa-plus add-vessel"
        aria-hidden="true"
        (click)="addItem()"></i>

    <i *ngIf="i !== 0 && canRemove" class="fa fa-minus add-vessel"
        aria-hidden="true"
        (click)="removeItem(i)"></i>

</div>
1
Why do you want to use a single mat-autocomplete? I know this doesn't answer the question but more background on the context may help to give an answer. Without any background or reasons, I would recommend you to just use a mat-autocomplete for each input. - arraintxo
@G.Tranter it is pretty clear what he is trying to do. You need to set an HTML-id (#auto in this example) in order to reference it in material's directive ([matAutocomplete]="auto"). But as far as I know there is no way to set an id dynamically in a template - Phil

1 Answers

0
votes

You have to use multiple auto complete elements and all the inputs need to bind with array of valueChanges event capturing functions. The reason is if you're trying to bind valueChanges with formArray ("items") then the function will execute number of time that how many inputs in the array. Use the following code to achieve target.

for(var i = 0;i<numberOfInputElements;i++){
    const items = this.form.get('items') as FormArray;
    this.filteredOptions[index] = items.at(index).get('item').valueChanges
        .pipe(
          startWith(''),
          map((value: string) => (value) ? this._filter(value, this.options) : this.options.slice())
        );
}