UncleJoe
UncleJoe

Reputation: 13

How to print a specific element in javascript? (print to PDF/paper)

I am currently working on my e-commerce website and I need to find a way to print the receipt.

I tried making a function that hides all elements except for the receipt but it was kinda ugly, hiding, then re-showing the other content.

Here's the receipt html if you need it:

.receipt {
  border-collapse: collapse;
  max-width: 80%;
  font-family: sans-serif;
}

.receipt td {
  padding: .5em;
}

.receipt tr:nth-child(even) {
  border: 1px solid #333;
  border-inline: none;
  background: #ddd;
}

.receipt tr:nth-child(odd) {
  background: #fff
}

.header-Uprice,
.item-Uprice,
.header-qty,
.item-qty {
  text-align: center
}

.total {
  border-bottom: 3px double #000
}
<table class="receipt">
  <tr class="table-headers">
    <td class="header-id">#</td>
    <td class="header-desc">Item Description</td>
    <td class="header-Uprice">Unit Price</td>
    <td class="header-qty">Qty</td>
    <td class="header-price">Price</td>
  </tr>
  <tr class="item" id="1">
    <td class="item-id">1</td>
    <td class="item-desc">Dummy Item1</td>
    <td class="item-Uprice">200$</td>
    <td class="item-qty">1</td>
    <td class="item-price">200$</td>
  </tr>
  <tr class="item" id="2">
    <td class="item-id">2</td>
    <td class="item-desc">Dummy Item2</td>
    <td class="item-Uprice">75$</td>
    <td class="item-qty">1</td>
    <td class="item-price">75$</td>
  </tr>
  <tr class="item" id="3">
    <td class="item-id">3</td>
    <td class="item-desc">Dummy Item3</td>
    <td class="item-Uprice">100$</td>
    <td class="item-qty">2</td>
    <td class="item-price">200$</td>
  </tr>
  <tr class="total">
    <td>Total</td>
    <td>
      <td>
        <td>
          <td>475$</td>
  </tr>
</table>

Upvotes: 0

Views: 1071

Answers (1)

developedbymark
developedbymark

Reputation: 254

Put your receipt specific styles inside the table then wrap the whole table inside a section like this:

<section class="receipt-section">
    <table class="receipt">
      <style> ... </style>
      <tr> ...
    </table>
</section>

now for the JS part:

  • we're gonna convert the raw HTML to a data uri containing ONLY the receipt table.
  • we insert inline JS that will print the receipt automatically after it loads.
  • EXTRA: since you probably want the receipt to also be centered, we can also inject extra css after loading the receipt (before printing).
function printReceipt() {
  const receipt = document.querySelector('.receipt');
  const css_centering = `document.querySelector(\'table > style\').innerHTML += \'.receipt { position: absolute; top: 20%; left: 50%; transform: translate(-50%, -50%) }\'`
  receipt.innerHTML += `<script>window.onload = () => { ${css_centering}; window.print(); }</script>`

  const receiptHTML = document.querySelector('.receipt-section').innerHTML;
  const URI = 'data:text/html,' + encodeURIComponent(receiptHTML);

  window.open(URI, '_blank'); // opening the receipt in a new blank page
}

if you want to link the function to a button:

const button = document.querySelector('.printButton');
button.addEventListener('click', printReceipt);

This might be one of the jankiest things I've made... but it works atleast. More experienced folks, you're welcome to edit this.

Upvotes: 2

Related Questions