monir
monir

Reputation: 47

How to Show total of multiple row values in to separate column of the table in angular 6?

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: image

StackBlitz Link

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

Answers (3)

invernomuto
invernomuto

Reputation: 10211

The simplest solution is to find the index of your current item in the grouped rows:

stackblitz

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

jcuypers
jcuypers

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

random
random

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

Related Questions