How to make a QR Code generator using JavaScript?

Murtuzaali Surti - Dec 23 '21 - - Dev Community

While you can generate QR codes for URLs in browsers such as Chrome, it's always interesting to learn how you can make your own version of a simple QR code generator. So, here we go.

HTML

Here's a quick look at the HTML code and it's pretty straightforward.




<section class="heading">
    <div class="title">QRcodes</div>
    <div class="sub-title">Generate QRCode for anything!</div>
</section>
<section class="user-input">
    <label for="input_text">Type something...</label>
    <input type="text" name="input_text" id="input_text" autocomplete="off">
    <button class="button" type="submit">Generate QR Code</button>
</section>
<div class="qr-code" style="display: none;"></div>
<script src="./js/app.js"></script>



Enter fullscreen mode Exit fullscreen mode

The last element is for the QR code to be displayed as soon as we fetch it from a library through javascript (more on that later).

Let's move on to some javascript.

JavaScript

First of all, we will create an event for when the user clicks on the Generate QR code button.




let btn = document.querySelector(".button");
btn.addEventListener("click", () => {
   //code
})



Enter fullscreen mode Exit fullscreen mode

Now, we are going to create a function known as generate() which will be invoked as soon as the user clicks on the Generate QR code button. This function will take the text input from the user as a parameter.




function generate(user_input) {
    //code
} 



Enter fullscreen mode Exit fullscreen mode

Inside this function, we are going to use a javascript library qrcode.js to generate QR code. You can use this library via a CDN by including the below <script> tag in the <head> tag of html.




<script src="https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js"></script>



Enter fullscreen mode Exit fullscreen mode

Inside the generate() function, we will create a new object using the given library. It will take two arguments, first is the element in which the QR code has to be displayed and secondly, the content for which the QR code has to be generated and some options to customize the QR code.




function generate(user_input) {
    var qrcode = new QRCode(document.querySelector(".qr-code"), {
        text: `${user_input.value}`,
        width: 180, //default 128
        height: 180,
        colorDark : "#000000",
        colorLight : "#ffffff",
        correctLevel : QRCode.CorrectLevel.H
    });
} 



Enter fullscreen mode Exit fullscreen mode

Next, we will create a download button and append it below the QR code.




let download = document.createElement("button");
document.querySelector(".qr-code").appendChild(download);



Enter fullscreen mode Exit fullscreen mode

Inside this download button we will add a link which allows users to download the QR code with a specified file name and append it into the download button. You can learn more about the download attribute here.




let download_link = document.createElement("a");
download_link.setAttribute("download", "qr_code_linq.png");
download_link.innerText = "Download";
download.appendChild(download_link);



Enter fullscreen mode Exit fullscreen mode

Let's figure out the href attribute of the <a> tag next.

The qrcode object will return a canvas element as well as an image element.

For smartphones, the canvas element will be visible but for desktop, the image element will be visible having a src attribute set to a dataURL. We will use the dataURL to download the QR code.

In the case of desktop, it's pretty obvious. We just have to grab the value of src attribute of the image element and assign it to the href attribute of the download link (<a> tag) after a specified amount of time (0.3 seconds) using setTimeout() function because the QR code takes some time to be generated.




let qr_code_img = document.querySelector(".qr-code img");
setTimeout(() => {
    download_link.setAttribute("href", `${qr_code_img.getAttribute("src")}`);
}, 300);



Enter fullscreen mode Exit fullscreen mode

But how do we get the dataURL from the canvas element? By using the method toDataURL() on the canvas element.




let qr_code_canvas = document.querySelector("canvas");
setTimeout(() => {
    download_link.setAttribute("href", `${qr_code_canvas.toDataURL()}`);
}, 300);



Enter fullscreen mode Exit fullscreen mode

After applying some logic, we get this:




if(qr_code_img.getAttribute("src") == null){
    setTimeout(() => {
        download_link.setAttribute("href", `${qr_code_canvas.toDataURL()}`);
    }, 300);
} else {
    setTimeout(() => {
        download_link.setAttribute("href", `${qr_code_img.getAttribute("src")}`);
    }, 300);
}



Enter fullscreen mode Exit fullscreen mode

Also, the .qr-code element will be hidden until the user clicks on the Generate QR code button. With this, our generate() function is all set to be invoked.




function generate(user_input){

    document.querySelector(".qr-code").style = "";

    var qrcode = new QRCode(document.querySelector(".qr-code"), {
        text: `${user_input.value}`,
        width: 180, //128
        height: 180,
        colorDark : "#000000",
        colorLight : "#ffffff",
        correctLevel : QRCode.CorrectLevel.H
    });

    console.log(qrcode);

    let download = document.createElement("button");
    document.querySelector(".qr-code").appendChild(download);

    let download_link = document.createElement("a");
    download_link.setAttribute("download", "qr_code_linq.png");
    download_link.innerText = "Download";

    download.appendChild(download_link);

    if(document.querySelector(".qr-code img").getAttribute("src") == null){
        setTimeout(() => {
            download_link.setAttribute("href", `${document.querySelector("canvas").toDataURL()}`);
        }, 300);
    } else {
        setTimeout(() => {
            download_link.setAttribute("href", `${document.querySelector(".qr-code img").getAttribute("src")}`);
        }, 300);
    }
}



Enter fullscreen mode Exit fullscreen mode

Now inside our click event function, we will check if there is already a QR code displayed or not. If it is, then we will first clear that QR code and generate a new one. If it's not present, we can simply generate a new one.

Also, all of this happens only if the user enters some text or if the input value is not empty.




btn.addEventListener("click", () => {
    let user_input = document.querySelector("#input_text");
    if(user_input.value != "") {
        if(document.querySelector(".qr-code").childElementCount == 0){
            generate(user_input);
        } else{
            document.querySelector(".qr-code").innerHTML = "";
            generate(user_input);
        }
    } else {
        document.querySelector(".qr-code").style = "display: none";
        console.log("not valid input");
    }
})



Enter fullscreen mode Exit fullscreen mode

You can style the elements the way as you want. Here are the styles that I went for:




:root{
    font-size: 62.5%;
}
*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    text-size-adjust: none;
    -webkit-text-size-adjust: none;
}
button:hover{
    cursor: pointer;
}

body{
    display: flex;
    flex-direction: column;
    align-items: center;
    background-color: #EAE6E5;
}
.heading{
    margin: 3rem 0 5rem 0;
}
.title, .sub-title{
    font-size: 4rem;
    text-align: center;
    font-family: 'Poppins', sans-serif;
    color: #12130F;
}
.sub-title{
    font-size: 1.5rem;
    color: #8F8073;
}

.user-input{
    display: flex;
    flex-direction: column;
    align-items: center;
    width: 100%;
}
.user-input label{
    text-align: center;
    font-size: 1.5rem;
    font-family: 'Poppins', sans-serif;
}
.user-input input{
    width: 80%;
    max-width: 35rem;
    font-family: 'Poppins', sans-serif;
    outline: none;
    border: none;
    border-radius: 0.5rem;
    background-color: #9b8774ad;
    text-align: center;
    padding: 0.7rem 1rem;
    margin: 1rem 1rem 2rem 1rem;
}
.button{
    outline: none;
    border: none;
    border-radius: 0.5rem;
    padding: 0.7rem 1rem;
    margin-bottom: 3rem;
    background-color: #5b92799d;
    color: #12130F;
    font-family: 'Poppins', sans-serif;
}

.qr-code{
    border-top: 0.5rem solid #8F8073;
    border-right: 0.5rem solid #8F8073;
    border-bottom: 1rem solid #8F8073;
    border-radius: 0.5rem;
    border-bottom-left-radius: 0.5rem;
    border-bottom-right-radius: 0.5rem;
    border-left: 0.5rem solid #8F8073;
    background-color: #8F8073;
}
.qr-code button{
    display: flex;
    justify-content: center;
    background-color: #8F8073;
    font-family: 'Poppins', sans-serif;
    color: #EAE6E5;
    border: none;
    outline: none;
    width: 100%; 
    height: 100%; 
    margin-top: 1rem;
}
.qr-code button a{
    width: 100%;
    height: 100%;
    text-decoration: none;
    color: #EAE6E5;
}



Enter fullscreen mode Exit fullscreen mode

Here is a demo of the entire project:

Here's the github repository for this project.

GitHub logo murtuzaalisurti / qr

A QR Code Generator and Reader! Generate as well as scan QR codes real quick!

That's all for now. I am on Twitter as well as GitHub.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . .