2

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?

2
  • 1
    I would think you could just change your component selector to a property, rather than a tag, like [appPersonRow] and then apply the selector to the tbody. Then you won't have the extra, non-table-compliant markup in the table Commented Jun 10, 2022 at 16:46
  • @BrandonTaylor I hadn't thought of this but it makes sense as long as I don't mind having lots of tbody elements in my table, which is fine and seems acceptable in HTML. Do you want to phrase this as an answer? Commented Jun 13, 2022 at 8:58

2 Answers 2

3

maybe there is no need for such a small component, maybe it's more convenient to have a person component representing the whole table, because the html elements of thetable are too interconnected

despite that...except using directive, you can set display: contents; to your table row component, but it is not supported in some browsers and there may be other consequences of "hiding" the host element

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the answer, but in my real code there definitely is a need for the component and because I may have a lot of rows I do need them to all be in the same table or I risk things getting broken up in weird ways. display: table-row-group is like a more refined display: contents specifically for this kind of case, but apparently not one that works very well!
2

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.