Я работаю над проектом на Angular 8, и я использовал ReactFrom, но он автоматически вызывает функцию addNewItem () и добавляет новую строку при нажатии клавиши Enter в любом поле в строке. Я также использовал AutocompleteLibModule из angular -ng-autocomplete для автозаполнения.
поставщик-счет-компонент. html
<div class="container-fluid">
<div class="row">
<div class="col">
<h2 class="text-center display-3 mb-2">Supplier Bill</h2>
</div>
</div>
<div class="row">
<div class="col">
<form [formGroup]="userTable">
<table class="table table-border">
<thead class="text-nowrap">
<th>Product Name</th>
<th>Comp</th>
<th>Pack</th>
<th>Batch</th>
<th>EXP</th>
<th>MRP</th>
<th>Rate</th>
<th>Qty</th>
<th>Bonus</th>
<th>SGST</th>
<th>CGST</th>
</thead>
<tbody>
<ng-container
formArrayName="tableRows"
*ngFor="let group of getFormControls.controls; let i = index"
>
<tr [formGroupName]="i">
<td>
<ng-autocomplete
#ngAutoCompleteStatic
[data]="medicines"
formControlName="productName"
[initialValue]=""
[searchKeyword]="keyword"
(inputChanged)="onChangeSearch($event)"
[itemTemplate]="itemTemplateStatic"
matInput
>
</ng-autocomplete>
<ng-template #itemTemplateStatic let-item>
<a [innerHTML]="item.productName"></a>
</ng-template>
</td>
<td>
<mat-form-field style="width: 60px !important;">
<input matInput type="text" formControlName="company" />
</mat-form-field>
</td>
<td>
<mat-form-field style="width: 60px !important;">
<input matInput type="text" formControlName="pack" />
</mat-form-field>
</td>
<td>
<mat-form-field style="width: 65px !important;">
<input matInput type="text" formControlName="batch" />
</mat-form-field>
</td>
<td>
<mat-form-field style="width: 50px !important;">
<input matInput type="text" formControlName="exp" />
</mat-form-field>
</td>
<td>
<mat-form-field style="width: 60px !important;">
<input matInput type="text" formControlName="mrp" />
</mat-form-field>
</td>
<td>
<mat-form-field style="width: 60px !important;">
<input matInput type="text" formControlName="rate" />
</mat-form-field>
</td>
<td>
<mat-form-field style="width: 50px !important;">
<input matInput type="text" formControlName="quantity" />
</mat-form-field>
</td>
<td>
<mat-form-field style="width: 60px !important;">
<input matInput type="text" formControlName="bonus" />
</mat-form-field>
</td>
<td>
<mat-form-field style="width: 30px !important;">
<input matInput type="text" formControlName="sgst" />
</mat-form-field>
</td>
<td>
<mat-form-field style="width: 30px !important;">
<input matInput type="text" formControlName="cgst" />
</mat-form-field>
</td>
<td>
<mat-icon class="delete" (click)="deleteRow(i)"
>delete_forever</mat-icon
>
<!-- <mat-icon class="done" (click)="doneRow(group)"
>done</mat-icon
> -->
</td>
<td>
<button
mat-raised-button
type="submit"
(click)="addNewItem()"
>
Add row
</button>
</td>
</tr>
<!-- <tr *ngIf="!group.get('isEditable').value">
<td>
{{ group.get("name").value }}
</td>
<td>
{{ group.get("email").value }}
</td>
<td>
{{ group.get("email").value }}
</td>
<td>
{{ group.get("bloodGroup").value }}
</td>
<td>
{{ group.get("mobNumber").value }}
</td>
<td>
<mat-icon class="edit" (click)="editRow(group)"
>edit</mat-icon
>
</td>
</tr> -->
</ng-container>
</tbody>
</table>
<div class="action-container">
<!-- <button mat-raised-button type="submit" (click)="addNewItem()">
Add row
</button> -->
<button
mat-raised-button
[disabled]="userTable.invalid"
type="submit"
(click)="submitForm()"
>
Submit
</button>
</div>
</form>
</div>
</div>
</div>
поставщик-счет-компонент.ts
import { Component, OnInit } from "@angular/core";
import { FormArray, FormGroup, FormBuilder } from "@angular/forms";
import { Observable, of } from "rxjs";
import { startWith, switchMap, delay, map } from "rxjs/operators";
import { MatOptionSelectionChange } from "@angular/material/core";
import { ApiService } from "../api.service";
import { MedicineService } from "../medicine.service";
import { Router } from "@angular/router";
@Component({
selector: "app-supplier-bill",
templateUrl: "./supplier-bill.component.html",
styleUrls: ["./supplier-bill.component.css"],
})
export class SupplierBillComponent implements OnInit {
userTable: FormGroup;
control: FormArray;
mode: boolean;
touchedRows: any;
constructor(
private fb: FormBuilder,
private api: ApiService,
private medicine: MedicineService,
private router: Router
) {}
keyword = "productName";
public medicines = <any>[];
ngOnInit(): void {
this.touchedRows = [];
this.userTable = this.fb.group({
tableRows: this.fb.array([]),
});
this.addNewItem();
}
ngAfterOnInit() {
this.control = this.userTable.get("tableRows") as FormArray;
}
initiateForm(): FormGroup {
return this.fb.group({
productName: [""],
company: [""],
pack: [""],
batch: [""],
exp: [""],
mrp: [""],
rate: [""],
quantity: [""],
bonus: [""],
sgst: [""],
cgst: [""],
});
}
addNewItem() {
const control = this.userTable.get("tableRows") as FormArray;
control.push(this.initiateForm());
}
deleteRow(index: number) {
const control = this.userTable.get("tableRows") as FormArray;
control.removeAt(index);
}
editRow(group: FormGroup) {
group.get("isEditable").setValue(true);
}
doneRow(group: FormGroup) {
group.get("isEditable").setValue(false);
}
saveUserDetails() {
console.log(this.userTable.value);
}
get getFormControls() {
const control = this.userTable.get("tableRows") as FormArray;
return control;
}
submitForm() {
const control = this.userTable.get("tableRows") as FormArray;
this.touchedRows = control.controls
.filter((row) => row.touched)
.map((row) => row.value);
console.log(this.touchedRows);
}
toggleTheme() {
this.mode = !this.mode;
}
onProductChange(i) {
let p = this.userTable.get("tableRows").get("");
console.log(i);
}
onChangeSearch(query: string) {
if (!query) return;
this.medicine.searchMedicine(query).subscribe((med: any) => {
// this.medicines = med;
// console.log(med.medicines);
this.medicines = med.medicines;
});
}
}