I have an Angular component that shows one or more table rows in a standard html table, like this:
<table>
<thead>
<tr>
<td>Person</td>
<td>Monday</td>
<td>Tuesday</td>
<td>Wednesday</td>
<td>Thursday</td>
<td>Friday</td>
<td>Total</td>
</tr>
</thead>
<tbody>
<person-row *ngFor="let person of people" ></person-row>
</tbody>
</table>
And then in person-row.component.html
:
<tr>
<td>{{person.name}}</td>
<td ngFor="let day of person.available">
{{day}}
</td>
<td>{{sumDays(person.available)}}</td>
</tr>
<tr *ngIf="editMode">
<td> Edit: </td>
<td ngFor="let day of person.available">
<!-- availability toggle checkbox -->
</td>
<td></td>
</tr>
In the parent component scss I direct the browser to ignore the person-row:
person-row {
display: table-row-group;
}
This all nearly works, but the resulting table still puts the whole person-row
content into the first column of the table.
Person | Monday | Tuesday | Wednesday | Thursday | Friday | Total |
---|---|---|---|---|---|---|
Alice yes yes no yes no 3 | ||||||
Bob no yes no no yes 2 | ||||||
edit [] [x] [] [] [x] [save] | ||||||
Claire no no yes yes yes 3 |
Note that this is a significant simplification over my existing code to demonstrate the problem, I am aware that in this case the edit row could simply be swapped in place!
Is it possible to show multiple rows using an angular component and have it fit into the existing table formatting, and if so how?
You can use a property selector and attach the *ngFor
to the tbody
element.
@Component({
selector: '[appPersonRow]',
template: `
<tr>
<td>{{person.name}}</td>
<td ngFor="let day of person.available">
{{day}}
</td>
<td>{{sumDays(person.available)}}</td>
</tr>
<tr *ngIf="editMode">
<td> Edit: </td>
<td ngFor="let day of person.available">
<!-- availability toggle checkbox -->
</td>
<td></td>
</tr>
`
})
export class PersonRowComponent {}
<table>
<thead>
<tr>
<td>Person</td>
<td>Monday</td>
<td>Tuesday</td>
<td>Wednesday</td>
<td>Thursday</td>
<td>Friday</td>
<td>Total</td>
</tr>
</thead>
<tbody [appPersonRow] *ngFor="let person of people">
</tbody>
</table>
You'll end up with multiple tbody
elements, but I can't see another way to iterate over two tr
elements at a time, as you can't bind a property selector to ng-container
.
If you don't want to have a separate component, you can use *ngFor
on an ng-container
and the HTML will be cleaner, but obviously you'll have a larger component.