my trung
my trung

Reputation: 57

Angular Binding data to table multi 'NgFor'

I have data_header and row list header_data:

 header = [
    { name: "Num#", value: "No" },
    { name: "Monday", value: "2" },
    { name: "Tuesday", value: "3" },
    { name: "Wednesday", value: "4" },
    { name: "Thursday", value: "5" },
    { name: "Friday", value: "6" },
    { name: "Saturday", value: "7" },
    { name: "Sunday", value: "8" },
    { name: "Time", value: "time" }
  ];

row list header_data:

datalist = [
    { No: 1, time: "06:30" },
    { No: 2, time: "07:30" },
    { No: 3, time: "08:30" },
    { No: 4, time: "09:30" },
    { No: 5, time: "10:30" }
  ];

I binding to html

<div class="table table-responsive">
    <table class="table table-bordered">
        <thead>
            <tr>
                <th *ngFor="let hd of header">
                    {{hd.name}}
                </th>
            </tr>
        </thead>
        <tbody>
            <tr *ngFor="let dt of datalist">
                <td *ngFor="let hd of header">
                    {{ dt[hd['value']] }}
                </td>
            </tr>
        </tbody>
    </table>
</div>

Now I have dataListDetail:

dataListDetail = [
    {
      day: 2,
      num: 3,
      colspan_column: 2,
      desc: "col_Monday && row_num_3 && colspan 2 "
    },
    {
      day: 5,
      num: 1,
      colspan_column: 3,
      desc: "col_Thursday && row_num_1 && colspan 3"
    }
  ];

Then, How do I can binding dataListDetail to table to result view? enter image description here

Link: Stackblitz Demo

Thank you!!!!

Upvotes: 1

Views: 912

Answers (1)

Eliseo
Eliseo

Reputation: 58099

One aproach (I don't know if it's the best) is create a grid array with rowspan and desc property. For create this grid, at first all elements are equal to {rowspan:1,desc:''}.

Then you loop over your "dataListDetail" and change the rowspan by 0 or the value of your "colspan". Some like

this.grid=this.datalist.map(x=>[{rowspan:1,desc:''},{rowspan:1,desc:''},{rowspan:1,desc:''},
           {rowspan:1,desc:''},{rowspan:1,desc:''},{rowspan:1,desc:''},{rowspan:1,desc:''}])

this.dataListDetail.forEach(x=>{
  const col=this.header.findIndex(c=>+c.value==x.day)-1
  this.grid[x.num-1][col].rowspan=x.colspan_column
  this.grid[x.num-1][col].desc=x.desc
  for (let i=1;i<x.colspan_column;i++)
  {
    this.grid[x.num-1+i][col].rowspan=0
  }
})

After,in your .html use this grid to show the values. We need take account that the fisrt td and the last td in the table not use "grid", use the values of the datalist[j].No and dataList[j].time

Some like

        <tbody>
            <tr *ngFor="let row of grid;let i=index">
                <td>{{datalist[i].No}}</td>
                <ng-container *ngFor="let col of row;let j=index;">
                    <td *ngIf="col.rowspan>=1" 
                         [style.background-color]="col.desc?'yellow':null"
                         [attr.rowspan]="col.rowspan>1?col.rowspan:null">
                        {{ col.desc|| '&nbsp;' }}
                    </td>
                </ng-container>
                <td>{{datalist[i].time}}</td>
            </tr>
        </tbody>

NOTE: I update the html to show in yellow if desc, not if col.rowspan>=1. this allow show in yellow an event with only need one cell

See the stackblitz

Upvotes: 4

Related Questions