Reputation: 47
I am using Angular 6 and html table. I have shown a json list data in to table. I want to show faculty wise total program applicant in to separate column ('Faculty Total') but i can't able to do this. Please guide me to solve this problem.
I want to do like this:
my ts file:
admitList = [
{
facultyName: 'FSIT',
programName: 'BSc in CSE',
programTotalApplicant: 10
},
{
facultyName: 'FSIT',
programName: 'BSc in SWE',
programTotalApplicant: 5
},
{
facultyName: 'FSIT',
programName: 'BSc in EEE',
programTotalApplicant: 15
},
{
facultyName: 'FAHS',
programName: 'BSc in LLB',
programTotalApplicant: 10
},
{
facultyName: 'FAHS',
programName: 'BSc in English',
programTotalApplicant: 5
},
{
facultyName: 'FAHS',
programName: 'BSc in Pharmacy',
programTotalApplicant: 8
}
];
constructor() { }
ngOnInit() { }
my html file:
<table class="table table-bordered">
<thead>
<tr>
<th>Faculty</th>
<th>Program</th>
<th>Program Total Applicant</th>
<th>Faculty Total</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let admit of admitList">
<td>{{admit.facultyName}}</td>
<td>{{admit.programName}}</td>
<td>{{admit.programTotalApplicant}}</td>
</tr>
</tbody>
</table>
Upvotes: 0
Views: 1510
Reputation: 10211
The simplest solution is to find the index of your current item in the grouped rows:
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'ngbd-datepicker-popup',
templateUrl: './datepicker-popup.html'
})
export class NgbdDatepickerPopup implements OnInit {
constructor() { }
ngOnInit() { }
rowspanBy(key: string){
return this.admitList.filter(ad => ad.shortName === key).length;
}
byIndex(admit: any){
const p1 = this.admitList.filter(ad => ad.shortName === admit.shortName);
return p1.indexOf(admit) === 0;
}
admitList = [
{
shortName: 'FSIT',
programName: 'BSc in CSE',
totalApplicant: 10
},
{
shortName: 'FSIT',
programName: 'BSc in SWE',
totalApplicant: 5
},
{
shortName: 'FSIT',
programName: 'BSc in EEE',
totalApplicant: 15
},
{
shortName: 'FAHS',
programName: 'BSc in LLB',
totalApplicant: 10
},
{
shortName: 'FAHS',
programName: 'BSc in English',
totalApplicant: 5
},
{
shortName: 'FAHS',
programName: 'BSc in Pharmacy',
totalApplicant: 8
}
];
}
<table class="table table-bordered">
<thead>
<tr>
<th>Faculty</th>
<th>Program</th>
<th>Total Applicant</th>
<th>Faculty Total</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let admit of admitList;">
<td>{{admit.shortName}}</td>
<td>{{admit.programName}}</td>
<td>{{admit.totalApplicant}}</td>
<td
[attr.rowspan]="rowspanBy(admit.shortName)"
*ngIf="byIndex(admit)"
>
{{rowspanBy(admit.shortName)}}
</td>
</tr>
</tbody>
</table>
All the best
Upvotes: 2
Reputation: 1794
Here's a full working solution: WORKING STACKBLITZ DEMO
component.ts
groupedFaculty;
ngOnInit() {
this.groupedFaculty = this.groupBy(this.admitList, 'shortName');
}
groupBy(objectArray, property) {
return objectArray.reduce(function (acc, obj) {
var key = obj[property];
if (!acc[key]) {
acc[key] = { count: 1, aggregation: obj.totalApplicant };
} else {
let count = acc[key].count + 1;
let aggregation = acc[key].aggregation += obj.totalApplicant;
acc[key] = { count: count, aggregation: aggregation } ;
}
return acc;
}, {});
}
component.html
<table class="table table-bordered">
<thead>
<tr>
<th>Faculty</th>
<th>Program</th>
<th>Total Applicant</th>
<th>Faculty Total</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let admit of admitList; let i = index ">
<td>{{admit.shortName}}</td>
<td>{{admit.programName}}</td>
<td>{{admit.totalApplicant}}</td>
<td *ngIf="(admitList[i-1]?.shortName != admitList[i]?.shortName) || (i == 0)" [attr.rowspan]="this.groupedFaculty[admitList[i]?.shortName].count">
{{this.groupedFaculty[admitList[i]?.shortName]?.aggregation}}
</td>
</tr>
</tbody>
</table>
Upvotes: 3
Reputation: 7891
First create a array grouped by shortname
and calculate total then add rowspan
attribute based on condition.
// HTML code
<table class="table table-bordered">
<thead>
<tr>
<th>Faculty</th>
<th>Program</th>
<th>Total Applicant</th>
<th>Faculty Total</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let admit of admitList; let i = index">
<td>{{admit.shortName}}</td>
<td>{{admit.programName}}</td>
<td>{{admit.totalApplicant}}</td>
<td *ngIf="i==0 || admit.shortName !== admitList[i-1].shortName" [attr.rowspan] = "(groupbyShortName[admit.shortName].count) ? groupbyShortName[admit.shortName].count : 0">{{groupbyShortName[admit.shortName].sum}}</td>
</tr>
</tbody>
</table>
// Component code
import {Component, OnInit} from '@angular/core';
@Component({
selector: 'ngbd-datepicker-popup',
templateUrl: './datepicker-popup.html'
})
export class NgbdDatepickerPopup implements OnInit {
groupbyShortName = {};
admitList = [
{
shortName: 'FSIT',
programName: 'BSc in CSE',
totalApplicant: 10
},
{
shortName: 'FSIT',
programName: 'BSc in SWE',
totalApplicant: 5
},
{
shortName: 'FSIT',
programName: 'BSc in EEE',
totalApplicant: 15
},
{
shortName: 'FAHS',
programName: 'BSc in LLB',
totalApplicant: 10
},
{
shortName: 'FAHS',
programName: 'BSc in English',
totalApplicant: 5
},
{
shortName: 'FAHS',
programName: 'BSc in Pharmacy',
totalApplicant: 8
}
];
constructor() {
this.groupbyShortName = this.admitList.reduce((accu, {shortName, totalApplicant, programName}) => {
if(!accu[shortName])
accu[shortName] = {count: 0, sum: 0, shortName, totalApplicant, programName};
accu[shortName].count += 1;
accu[shortName].sum += totalApplicant;
return accu;
}, {});
}
ngOnInit() { }
}
Upvotes: 2