I'm using PrimeNG 14 (and Angular 14). I have a form in which I enter product information, and I would like to associate the product with one or more categories, each of which is displayed as a checkbox.
<form [formGroup]="form" (ngSubmit)="submit()">
...
<p-table #dt [value]="(categories$ | async)!"
[(selection)]="selectedCategories"
dataKey="categoryId">
<ng-template pTemplate="header">
<tr>
<th>
<p-tableHeaderCheckbox></p-tableHeaderCheckbox>
</th>
<th pSortableColumn="name">
<div>
Category
<p-sortIcon field="name"></p-sortIcon>
<p-columnFilter type="text" field="name" display="menu"></p-columnFilter>
</div>
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-category>
<tr >
<td>
<p-tableCheckbox [value]="category" [formControl]="$any(form.controls['categoryIds'])"></p-tableCheckbox>
</td>
<td>
<span >Category</span>
{{category.name}}
</td>
</tr>
</ng-template>
</p-table>
In my service class I have
form!: FormGroup;
...
ngOnInit(): void {
...
this.form = this.fb.group({
...
categoryIds: []
});
The issue is, I'm not sure how to bind the category ID checkboxes to the form control. Using the above approach doesn't work because when I check one checkbox, they all get checked.
CodePudding user response:
To bind the checkboxes to the form control, you can use the formControlName attribute on each checkbox element. Here's how you could update your code:
<form [formGroup]="form" (ngSubmit)="submit()">
...
<p-table #dt [value]="(categories$ | async)!"
[(selection)]="selectedCategories"
dataKey="categoryId">
<ng-template pTemplate="header">
<tr>
<th>
<p-tableHeaderCheckbox></p-tableHeaderCheckbox>
</th>
<th pSortableColumn="name">
<div>
Category
<p-sortIcon field="name"></p-sortIcon>
<p-columnFilter type="text" field="name" display="menu"></p-columnFilter>
</div>
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-category>
<tr >
<td>
<input type="checkbox" formControlName="categoryIds" [value]="category.categoryId">
</td>
<td>
<span >Category</span>
{{category.name}}
</td>
</tr>
</ng-template>
</p-table>
</form>
Note that in the code above, we are using the formControlName attribute to bind each checkbox to the categoryIds control in the form group, and the value attribute to specify the value of the checkbox.
When the form is submitted, you can access the selected category IDs using the value property of the categoryIds control, e.g. this.form.controls['categoryIds'].value.
CodePudding user response:
You can use the formArrayName
attribute on the p-tableCheckbox
element, and provide the name of the form array control as the value.
<form [formGroup]="form" (ngSubmit)="submit()">
...
<p-table #dt [value]="(categories$ | async)!"
[(selection)]="selectedCategories"
dataKey="categoryId">
<ng-template pTemplate="header">
<tr>
<th>
<p-tableHeaderCheckbox></p-tableHeaderCheckbox>
</th>
<th pSortableColumn="name">
<div>
Category
<p-sortIcon field="name"></p-sortIcon>
<p-columnFilter type="text" field="name" display="menu"></p-columnFilter>
</div>
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-category>
<tr >
<td>
<p-tableCheckbox [value]="category" formArrayName="categoryIds"></p-tableCheckbox>
</td>
<td>
<span >Category</span>
{{category.name}}
</td>
</tr>
</ng-template>
</p-table>
In your service class, you can then create a FormArray
control with the name categoryIds
and add it to the form group:
ngOnInit(): void {
...
this.form = this.fb.group({
...
categoryIds: this.fb.array([])
});
}
This will allow each checkbox to be bound to the corresponding element in the categoryIds
form array control, and will allow you to submit the selected category IDs as part of the form data.