Issue
I’m trying to print the modal contents of ng-bootstrap modal in Angular. The modal contains a table and so I want the doc to be printed in same format. I want the same functionality given here but unable to implement it.
According to this link, it sets the visibility of body
to hidden
during print and shows only modal content. But in Angular, we use components and so setting body: hidden
doesn’t work. It prints out the whole document (modal along with background component, header and footer which I don’t want).
I’ve followed alot of solutions but unable to do so.
I’ve also tried appending the printable modal content to new window but writing to new window requires only strings. I’m using table in modal so I want the same style of table to get print.
How can I achieve this?
Edit 1 : This is the modal content I want to print:
<div id="printable">
<div class="row shipping">
<div class="col-4">
<h6>SHIPPING ADDRESS</h6>
<p>
{{ this.order.shipName }} : {{ this.order.addrLine1 }},
{{ this.order.area1 }}, {{ this.order.area2 }},
{{ this.order.countryCode }} - {{ this.order.pin }}
</p>
</div>
<div class="col-4">
<h6>SHIPPING METHOD</h6>
<p>Standard</p>
</div>
<div class="col-4">
<h6>ACCOUNT PAID</h6>
<p>Paypal Account: {{ this.order.order.payerEmail }}</p>
</div>
</div>
<br /><br />
<div class="card">
<table>
<tr>
<th>ITEM</th>
<th>DETAILS</th>
<th>QTY</th>
<th>TOTAL</th>
</tr>
<tr>
<td>
<img
[src]="this.order.order.image"
style="height: 70px; width: 70px"
/>
</td>
<td>
{{ this.order.order.category }}
</td>
<td>{{ this.order.order.quantity }}</td>
<td>${{ this.order.order.amtPaid }}</td>
</tr>
</table>
</div>
<br />
<div class="row" style="padding-bottom: 20px">
<div class="col-8"></div>
<div class="col-md-4">
<h5>
<b>ORDER TOTAL</b> : <span>${{ this.order.order.amtPaid }}</span>
</h5>
<br />
</div>
</div>
</div>
</div>
On button click, I want to print this div content as it is
<div class="modal-footer" id="non-printable">
<button type="button" class="btn btn-primary" (click)="onPrint()">
Print Receipt
</button>
<button
type="button"
class="btn btn-secondary"
(click)="modal.dismiss('cancel click')"
>
Cancel
</button>
</div>
Method to print the modal content:
onPrint() {
var elem = document.getElementById("printable");
var domClone = elem.cloneNode(true)
var $printSection = document.getElementById("printSection");
if (!$printSection) {
let $printSection = document.createElement("div");
$printSection.id = "printSection";
document.body.appendChild($printSection);
$printSection.innerHTML = "";
$printSection.appendChild(domClone);
window.print(); // only modal content should get print
}
}
In css:
@media screen {
#printSection {
display: none;
}
}
@media print {
body * {
visibility:hidden;
}
#printSection, #printSection * {
visibility:visible;
}
#printSection {
position:absolute;
left:0;
top:0;
}
}
Thanks
Solution
No need the js code to clone and all its just a css change in the code
onPrint() {
window.print();
}
For hiding the header, footer and other stuff that are beyond the scope of the component has to written in global css file i.e. in style.css
/*
move from component level css to style.css
Here hiding is not required as the same is been displayed on screen
@media screen {
#printable {
display: none;
}
} */
@media print {
body * {
visibility:hidden;
}
#printable, #printable * {
visibility:visible;
}
#printable {
position:absolute;
left:0;
top:0;
}
}