0

I'm trying to make a list of inputs mat autocomplete but I have an error of types in FormControl and duplicates data. I want to do dynamic mat autocompletes to set The list of items to later post. By having the name myControl for the input, as I add inputs to the list of items, they are overwritten. I want to know how to generate ids and access them in ts to manage the data.

I leave you the code and images so you can see the problem.

I have tried to dynamically create the formControl or a formControlName but I still don't understand how to generate it in the TS.

<!-- Modal body -->
            <div class="grid grid-cols-6 xl:grid-cols-6 gap-4 px-4 py-4">
                @for (i of items; track i) {
                    <div class="w-full h-20 rounded-xl col-span-2">
                        <mat-form-field class="example-full-width">
                            <mat-label>Producto</mat-label>
                            <input type="text"
                                   placeholder="Selecciona"
                                   aria-label="Producto"
                                   matInput
                                   [formControl]="myControl"
                                   [matAutocomplete]="auto">
                            <mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
                                <mat-option value=""></mat-option>
                              @for (dbi of filteredOptions | async; track dbi) {
                                <mat-option (onSelectionChange)="changeSelection(i.id)" id="{{i.id}}" [value]="dbi.name">{{dbi.name}}</mat-option>
                              }
                            </mat-autocomplete>
                          </mat-form-field>
                    </div>
  items = [{id: 0, name: '', units: 0, price: 0, totalConcept: 0}];
  data = [];
  dbItems:any = [];
  apiService = inject(ApiService);
  myControl = new FormControl('');
  filteredOptions!: Observable<any[]>;
  lastOptionIdSelected:number = 0;
  lasItemAdded: any = {};

  constructor(public dialogRef: MatDialogRef<BudgetDetailsComponent>){}

  ngOnInit() {
    if(this.data.length > 0){
      this.items = this.data;
    }

    this.filteredOptions = this.myControl.valueChanges.pipe(
      startWith(''),
      map(value => this._filter(value || '')),
    );
  }

  onClose(): void {
    if(this.items[this.items.length - 1].totalConcept == 0){
      this.items.pop();
    }
    this.dialogRef.close({data: this.items});
  }

  addItem(id:number){
    let unitsInput = document.getElementById('units'+id) as HTMLInputElement;

    this.items[id].name = this.lasItemAdded.name;
    this.items[id].units = parseFloat(unitsInput.value);
    this.items[id].price = parseFloat(this.lasItemAdded.priceU);
    this.items[id].totalConcept = parseFloat(unitsInput.value) * parseFloat(this.lasItemAdded.priceU.value);

    this.items.push({id: id+1, name: '', units: 0, price: 0, totalConcept: 0});
  }

  changeSelection(id: number){
    this.lastOptionIdSelected = id;
  }

  private _filter(value: any): any[] {
    const filterValue = value.toLowerCase();

    let itemSelected = this.dbItems.find((item:any) => item.name === value)!;

    if(itemSelected !== undefined) {
      let priceElement = document.getElementById(`priceTD${this.lastOptionIdSelected}`)! as HTMLInputElement;
      priceElement.value = itemSelected.priceU;
    }

    this.lasItemAdded = itemSelected;

    return this.dbItems.filter((option:any) => option.name.toLowerCase().includes(filterValue));
  }

img

0

Browse other questions tagged or ask your own question.