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>
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
})
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
}
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>
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
});
}
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);
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);
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);
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);
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);
}
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);
}
}
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");
}
})
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;
}
Here is a demo of the entire project:
Here's the github repository for this project.
Top comments (29)
Thank you for the article. It shows how to generate a QR Code which can be helpful. However I suggest you change the title to
Creating a QR Code with JavaScript
because the termVanilla JS
refers to using pure JavaScript. When I read the title I clicked the article because I thought you were actually showing it withVanilla JS
but instead you are using a library which is notVanilla JS
. Try to imagine this: I tell someone "How to get a DOM Element with VanillaJS" and then I show how to load jQuery to then query with jQuery the DOM Element.Again: The article in itself is helpful but the title very misleading.
A number of issues here....
You're using a submit button without a form. Adding a form would actually be better too, as you could generate the QR code by also pressing return to submit the form. This is standard, expected behaviour on a form.
You're repeatedly calling
document.querySelector
to get the same things. Would be better just to call it once.If you have an element with an
id
- you don't need to usedocument.querySelector('#id')
at all - the element will already be available aswindow.id
, or justid
.Putting all of this together, you can simplify your code considerably.
Also, this isn't really a QR code generator at all - it's an interface to call a 3rd party function that generates a QR code. You should try writing such a generator yourself - it's quite interesting, and you find out how QR codes work.
I agree to everything but the ID approach. Using global definitions is not recommended as there is technically no guarantee it's gonna be the DOM Element (stackoverflow.com/a/18713391/1236627).
In simple code like your example, you can guarantee it
Context-free, yes. But that wasn't my point. The point is that it is generally not recommended besides for e.g. CodePens or Debugging sessions so I recommend to be careful with that advice. (Or in other words: Even in a large-scale enterprise application I could state "but here it is working" - which then only holds true as long as the overall context (switching libraries, new employees adding new code, etc) does not change. Which is not a good idea.)
Yup - agree. It's appropriate to use in the right context. It should never be avoided just because people "don't understand it" or "aren't used to doing it that way" - way too much of that goes on these days
The problem is that this is viewed from a "small context perspective". In production, as stated, it shouldn't be recommended to be used.
It goes the same principle as always e.g. Security through Obfuscation is definitely working in the right context. But it's recommended to be avoided at all costs in programming because it opens up an option to be breached.
And the similiar goes for
window[[id]
. If being used in non-prod envs such as showing something or Sandboxes then it can be very helpful (this is where I actually do use it).But for prod it should be avoided as a guideline. Generally in JS we try to modularize more to enable teams to scale and be free from dependencies from other teams.
Now imagine one team has the idea of using
window[id]
for their component that they are building. And say both teams are using e.g. asubmitButton
which is very likely. Now because they allowed themselves to do so they would be allowed to addid="submitButton"
. So not only now the ID is double-placed but also thewindow[id]
is ambigious. So the teams are suddenly very dependent on each other, communication effort increases, etc.On top of that comes another problem: You are polluting the global context. Libraries are polluting the global context too - because they have to. E.g. analytics libraries might expose
const analytics = whatever
in the window scope. That happens in enterprise applications extremely often because the 3d-party tracking tool needs access to it. Theconst analytics
now takes precedence over any DOM ID definition. So now the approach of usingwindow[domId]
wouldn't work anymore.In any prod-bound or team-bound contexts where more than 1 person works or anything is supposed to scale in the future this should definitely not be used.
From the HTML spec:
The only reason this feature hasn't been removed is that (as with many other bizarre features of the early Web) it can't be changed without breaking legacy code. It's the same reason you can write
<body bgcolor="butts">
and get a handsome brick-red background for your page.Yup I agree that I used a JS library but this is actually a beginner friendly tutorial to make a QR code generator web app on your own.
🙌 Thanks for sharing this amazing article, Murtuzaali! 🤓
I found the step-by-step instructions on how to create a QR code generator using JavaScript to be super helpful. 🤩
I've been wanting to learn more about QR codes and how they can be used in Salesforce, so your article was timely. 🤑
I also recently read the article on How to Use QR Codes in Salesforce and found it to be a great complement to your article. 🤞
Both pieces of content provided valuable insights on the potential uses and benefits of QR codes in Salesforce. 💪
Keep up the great work!
Thank You!
There's a Barcode Detection API in modern browsers. You'd only need to polyfill it if it is not supported.
Which is helping for Detection, not for creation. But thanks for the hint 👍
It's not available for all browsers. Thanks for suggesting, I didn't knew about this earlier!
Interesting article but the title is misleading. Neither vanilla flavour nor generating anything
This is an article which appeals to beginners!
Does not mean that the title should be misleading!
changed
Open source is essential for application developers. It is unfortunate that Open Base is shutting down. If you are looking for an alternative, check out kandi from Open Weaver. kandi helps developers build applications faster through open source reuse. Through its natural language interface, kandi recommends code snippets, packages, libraries and solutions from 650 Million open source assets. kandi also promotes responsible reuse with proper license attribution across all assets, while guiding the developer on paring code snippets with libraries to build their applications faster.
Try kandi at kandi.openweaver.com. Thank you for your support to the open source community and happy coding!
Hey guys,
Is there any library for react-native ??? I need to design stylish qr code.
this might help openbase.com/categories/js/best-re...
Open source is essential for application developers. It is unfortunate that Open Base is shutting down. If you are looking for an alternative, check out kandi from Open Weaver. kandi helps developers build applications faster through open source reuse. Through its natural language interface, kandi recommends code snippets, packages, libraries and solutions from 650 Million open source assets. kandi also promotes responsible reuse with proper license attribution across all assets, while guiding the developer on paring code snippets with libraries to build their applications faster.
Try kandi at kandi.openweaver.com. Thank you for your support to the open source community and happy coding!
Thanks, I will explore it.
Build Full QR Code Generator Website using JavaScript
QR Code Generator of Link, Text, Phone, Vcard, Message, App Links
Copy QR Code Image to Clipboard
Download QR Code Image
Change QR Code Size and Color
demo tutorial and source code: bit.ly/3OZcxBH
You can't call it vanilla, because you are using an library. I think pure vanilla javascript qr code is not even possible.
changed on demand
Why setTimeout? Why not async/await?
Because we don't return any promises which can be resolved!