0

I want to display items names in a table but limit to number of rows is three. If there are more than 3 items then 4th item should be in 2nd column, if there are more than 6 items then 7th item should be in 3rd column. I am using normal table.

<table>
    <tr *ngFor="let item of group">
        <td>{{item}}</td>
    </tr>
</table>

Please let me know what condition I have to give, to limit number of rows and get them in columns based on number of items.

ppwater
  • 2,315
  • 4
  • 15
  • 29
Saran S
  • 39
  • 1
  • 6
  • Consider use Angular-Material... https://material.angular.io/components/table/api These and othe more features very helpful you can find – Hector May 29 '23 at 13:29

2 Answers2

2

You can use CSS Grid to arrange this sort of layout using grid-auto-flow. To get you started here's a few resources:

Your layout using grid can be seen below. I've annotated the pertinent bits:

.table {
  display: grid;
  grid-auto-flow: column; /* make the items fill up the grid container by column and not row */
  grid-template-rows: repeat(3, 1fr); /* have a max number of 3 rows and make them all the same height */
  gap: 0.125rem; /*put a small gap between each element */
}

.table > div {
  background-color:teal;
  padding: 0.5rem 1rem;
}
<div class="table">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
</div>
Adam
  • 5,495
  • 2
  • 7
  • 24
0

@Adam has posted the correct answer for this using CSS methods.

If you are looking to manually solve this through data manipulation, then this is a solution for you.

export class UsersComponent {
  // Your data
  group: Array<string> = ['A', 'B', 'C', 'D'];
  // Fixed number of rows
  rows: number = 3;
  // Calculate number of columns based on data length and required number of rows
  columns: number = Math.ceil(this.group.length / this.rows);

  // We will push data here
  data: any = [];

  constructor() {
    // counter for data
    let elem = 0;
    // Outer loop
    for (let i = 0; i < this.columns; ++i) {
      // Create a row in data
      this.data.push([]);
      // Inner Loop
      for (let j = 0; j < this.rows; ++j) {
        // Do not push undefined elements (if any)
        if (this.group[elem]) {
          this.data[i][j] = this.group[elem];
        }
        // increment counter
        elem++;
      }
    }
    // We got the data, now lets take the transpose to invert it.
    this.data = this.transpose(this.data);
    console.log(this.data);
  }

  // Credits: https://stackoverflow.com/questions/17428587/transposing-a-2d-array-in-javascript
  transpose(matrix: any) {
    return matrix[0].map((col: any, i: any) =>
      matrix.map((row: any) => row[i])
    );
  }
}

Now that we have data in 2d format (with correct number of rows and columns), you can display it in your HTML like:

<table class="table">
  <tr *ngFor="let row of data">
    <span *ngFor="let column of row">
      <td *ngIf="column">{{ column }}</td>
    </span>
  </tr>
</table>

It is possible to change ordering of elements appearing in a row (populate row first or populate columns first) just by tweaking outer and inner loops in code. Also you can change number of rows and size of your data to test it for various cases.

Demo here https://stackblitz.com/edit/angular-mgte7k?file=src%2Fusers%2Fusers.component.ts

Syed Rafay
  • 1,405
  • 2
  • 15
  • 19