1

I'm using this library which generates QR codes as PNG images: https://davidshimjs.github.io/qrcodejs/

I want to have a download button for the generated QR code, however the canvas only appear when the image is generated. Any tips on how to put a download button?

Here's my sample code for my project:

PHP:

<div>
    <!-- <input type="text" id="qr-data" value="<?php echo uniqid();; ?>"/> -->
    <button onclick="generateQR()">Generate</button>
    <div id="qrcode"></div>
    <script src="qrcode.min.js"></script>
</div>

Javascript:

<script>
    var qrdata = document.getElementById("qr-data");
    var qrcode = new QRCode(document.getElementById("qrcode"));

    function generateQR() {
        var data = qrdata.value;
        qrcode.makeCode(data);
    }
</script>
Don't Panic
  • 13,965
  • 5
  • 32
  • 51
JungProg
  • 27
  • 4

1 Answers1

2

A quick search turns up a simple way to download an image when clicking on it:

  • we need a link;
  • with a download attribute;
  • with the same href as the image src;

The image src we're after doesn't exist until the code is generated. So we need to dynamically copy it once it is created. So we'll need to add a download link/button to your HTML, and to copy the QR code src to the link href after it is generated.

So first up, add the link:

<a id="download" href="" download="qr.png"><button>Download</button></a>

Next, we need to copy the generated src. One catch is that we need to wait for the QR code to be generated before we can copy it. Trying to do the copy immediately after your makeCode() line does not work, because makeCode() takes some time to run, and runs asynchronously. That means code immediately after that line will run before makeCode() has finished - we can't copy the src before the src exists!

There are no documented success- or done-type events or callbacks for QRCode.js, so the safest option seems to be to do it later, when the download button is clicked. So add an event listener for our download link:

var link = document.getElementById("download");
link.addEventListener("click", setUpDownload);

And add the setUpDownload() function which actually does the copy:

function setUpDownload() {
    // Find the image inside the #qrcode div
    var image = document.getElementById("qrcode").getElementsByTagName("img");

    // Get the src attribute of the image, which is the data-encoded QR code
    var qr = image[0].src;

    // Copy that to the download link
    link.href = qr;
}

And we're done! Working JSFiddle.

Side Note

It is considered best practice to separate your HTML from your JS. That means using event handlers in JS, rather than using inline onclick(). I'd suggest changing this:

<button onclick="generateQR()">Generate</button>

To this (give it an id to make it easy to reference later):

<button id="button">Generate</button>

And adding an event listener in your JS to do the same job:

var button = document.getElementById("button");
button.addEventListener("click", generateQR);
Don't Panic
  • 13,965
  • 5
  • 32
  • 51