1

I have a header component and home component. In header component a download button is there, When I click download button the content of home component will be download,so I need to access the div id(content) of home component from header component. I am not getting how to do it.

header.component.html

<button (click)="generarPDF()" type="button" class="btn btn-primary">Download</button>
<nav *ngIf="router.url !== '/' && router.url !== '/login'" class="mb-3 navbar navbar-expand-sm bg-dark-custom navbar-dark">
  <!-- Brand/logo -->
  <a class="navbar-brand" routerLink="/"><img class="img-responsive" src="../assets/logo.png"></a>
</nav>

header.component.ts

import { Component, OnInit } from '@angular/core';
import { Router }  from "@angular/router";

@Component({
  selector: 'app-header',
  templateUrl: './header.component.html',
  styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {

  constructor(public router: Router){} 

  ngOnInit() {
  }

}

home.component.html

<div class="container-fluid" id="content">
  <div class="row">
    <div class="col-md-6">
      <div class="mb-3 text-left">
        <div>Total Expenses are: <b>Rs. {{this.sum}}</b></div>
      </div>
    </div>
    <div class="col-md-6">
      <div class="mb-3 text-right">
        <input [(ngModel)]="searchText" autocomplete="off" class="col-md-6 searchinput" type="text"
          placeholder="Search.." />
      </div>
    </div>
  </div>
  <div class="row">
    <div class="col-md-12">
      <table class="table table-bordered expensetable">
        <thead>
          <tr>
            <th>Date</th>
            <th>Treatment</th>
            <th>Expenses (INR)</th>
            <th>Results</th>
          </tr>
        </thead>
        <tbody>
          <ng-container *ngIf="( getListData | filter:searchText) as result">
            <tr *ngFor="let item of result">
              <td>{{item.Date}}<div><small>({{item.day}})</small></div>
              </td>
              <td [innerHtml]="getTreatment(item.Treatment)"></td>
              <td>{{item.Expenses}}</td>
              <td><span placement="left" ngbTooltip="{{item.Description}}" class="{{item.Result}}"><i
                    class="las la-info-circle info"></i> Info</span></td>
            </tr>
            <tr *ngIf="result.length === 0">
              <td colspan="4" class="text-center">No Data Found</td>
            </tr>
          </ng-container>
        </tbody>
      </table>
    </div>
  </div>
</div>

home.component.ts

import { Component, OnInit,ViewChild, ElementRef} from '@angular/core';
import { CommonserviceService } from './../utilities/services/commonservice.service';
import {NgbModal, ModalDismissReasons} from '@ng-bootstrap/ng-bootstrap';
import jsPDF from 'jspdf';
import html2canvas from 'html2canvas';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
  getListData: any;
  sum:number;
  constructor(private modalService: NgbModal,private commonserviceService: CommonserviceService) { }
  @ViewChild('content', { 'static': true}) content:ElementRef;
  
  ngOnInit() {
      this.getHeroes();
  }
  getTreatment(data) {
    console.log(data);
    let str = '<div class="demooutput">'
    let arr = data.split(',');
    if (arr.length > 0) {
      for (let i = 0; i < arr.length; i++) {
        str += '<span class="' + arr[i] + '">' + arr[i] + '</span>'
      }
    }
    str += '</div>'
    return str
  }
getHeroes(){
   this.commonserviceService.getData().subscribe(getListData =>{
          this.getListData = getListData;
          console.log(this.getListData);
          this.sum=0;
  for(let a of this.getListData){
  this.sum=this.sum+a.Expenses;
     
  }
   console.log(this.sum);
  },
      (error) => {
      alert('No data');
      }
  );
}

generarPDF() {
  
  const div = document.getElementById('content');
  const options = {
    background: 'white',
    scale: 3
  };

  html2canvas(div, options).then((canvas) => {

    var img = canvas.toDataURL("image/PNG");
    var doc = new jsPDF('l', 'mm', 'a4', 1);

    // Add image Canvas to PDF
    const bufferX = 5;
    const bufferY = 5;
    const imgProps = (<any>doc).getImageProperties(img);
    const pdfWidth = doc.internal.pageSize.getWidth() - 2 * bufferX;
    const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
    doc.addImage(img, 'PNG', bufferX, bufferY, pdfWidth, pdfHeight, undefined, 'FAST');

    return doc;
  }).then((doc) => {
    doc.save('postres.pdf');  
  });
}
}

app.component.html

<app-header></app-header>
<router-outlet></router-outlet>
<app-footer></app-footer>

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'sampleproject';
}
UIAPPDEVELOPER
  • 583
  • 5
  • 18
  • 37
  • you have to user parent-child component concept. https://angular.io/guide/component-interaction – Avinash Dalvi Jul 04 '20 at 19:43
  • try this document object access -- > https://stackoverflow.com/questions/43542373/angular2-add-class-to-body-tag – LogicBlower Jul 04 '20 at 19:51
  • You should not be constructing HTML in your getTreatment() method. Look at using an *ngFor in the template instead. – wlf Jul 04 '20 at 22:42

1 Answers1

0

You can do it using an output/eventEmitter on your parent component, but you would need to include the <app-header> in the home component rather than the app component.

If you want to keep the <app-header> in the app component you'll need another approach, potentially using a service to communicate between the header and the home components.

header.component.html

<button (click)="downloadClicked.emit(null)" type="button" class="btn btn-primary">Download</button>

header.component.ts

export class HeaderComponent implements OnInit {

  @Output() 
  downloadClicked: EventEmitter<any> = new EventEmitter();

  constructor(public router: Router){} 

  ngOnInit() {
  }   
}

home.component.ts

<app-header (downloadClicked)="generarPDF()"></app-header>
<div class="container-fluid" id="content">
...

app.component.html

<router-outlet></router-outlet>
<app-footer></app-footer>
wlf
  • 3,086
  • 1
  • 19
  • 29