Skip to content
Go back

Hello, Web Components(2) — Component Generate QR Code

Updated:

Now It time to make advance components, by create component for generate qr code

let’s go :)

WebComponents2

Table of contents

Open Table of contents

Getting started

reference:

How To Create QR Codes With JavaScript

Hand Print Scanning Animation Effects | Html CSS

Let’s coding

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>QR Code Component</title>
  </head>
  <body>
    <qrcode-component></qrcode-component>
    <script type="module" src="qrcode-component.js"></script>
  </body>
</html>index.html

Script

export class QrCode extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: "open" });
    this.QR_URL =
      "https://cdnjs.cloudflare.com/ajax/libs/qrcode/1.4.4/qrcode.js";
    this.FONT_URL =
      "https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap";
  }

  connectedCallback() {
    this.loadQRCodeScript().then(() => {
      this.renderTemplate();
      this.onClickBtGenerate();
      this.onClickBtClear();
      this.input = this.shadowRoot.querySelector("#inputUrl");
      this.image = this.shadowRoot.querySelector("#qrCodeImage");
      this.boxResult = this.shadowRoot.querySelector(".qr-result");
    });
  }

  loadQRCodeScript() {
    return new Promise((resolve, reject) => {
      if (window.QRCode) return resolve();

      const script = document.createElement("script");
      script.src = this.QR_URL;
      script.onload = resolve;
      script.onerror = reject;
      document.head.appendChild(script);
    });
  }

  renderTemplate() {
    this.shadowRoot.innerHTML = `
       <link rel="stylesheet" href="qrcode-component.css">
         <style>
          @import url(${this.FONT_URL});
          div {
            font-family: 'Roboto', sans-serif;
          }
        </style>
        ${this.template().trim()}
     `;
  }

  template = () => {
    return `
     <div class="qr-box">
      <div class="qr-input">
        <h1>QR Generator</h1>
        <div class="inputs">
          <input type="text" id="inputUrl" placeholder="Please enter url" />
          <button type="button" class="bt-clear-input">
            <svg
              width="16"
              height="16"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
            >
              <line x1="18" y1="6" x2="6" y2="18"></line>
              <line x1="6" y1="6" x2="18" y2="18"></line>
            </svg>
          </button>
        </div>
        <button type="button" class="bt-generate">Generate QR Code</button>
      </div>
      <div class="qr-result">
        <img id="qrCodeImage" />
      </div>
    </div>
    `;
  };

  onClickBtGenerate() {
    this.shadowRoot
      .querySelector(".bt-generate")
      .addEventListener("click", async () => {
        let url = this.input.value;
        if (url === "") return;

        this.clearState();
        await this.delay(500);

        const dataUrl = await QRCode.toDataURL(url);
        this.render(dataUrl);
      });
  }

  onClickBtClear() {
    this.shadowRoot
      .querySelector(".bt-clear-input")
      .addEventListener("click", async () => {
        this.input.value = "";
      });
  }

  clearState = () => {
    this.image.src = "";
  };

  delay = ms => {
    return new Promise(resolve => setTimeout(resolve, ms));
  };

  render(dataUrl) {
    this.image.src = dataUrl;
  }
}

customElements.define("qrcode-component", QrCode);qrcode-component.js

Style

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

button {
  all: unset;
  cursor: pointer;
}

input {
  width: 100%;
  padding: 8px 24px 8px 8px;
  border: 2px solid #e5e7eb;
  border-radius: 12px;
  font-size: 14px;
  transition: all 0.3s ease;
  background: #f9fafb;
}

.qr-box {
  max-width: 240px;
  padding: 16px;
  text-align: center;
  border: solid 1px gray;
  border-radius: 4px;

  & h1 {
    font-size: 24px;
  }

  .qr-input {
    display: flex;
    gap: 8px;
    flex-direction: column;
    margin-bottom: 8px;

    .inputs {
      position: relative;
    }

    .bt-clear-input {
      position: absolute;
      width: 16px;
      height: 16px;
      right: 8px;
      top: 10px;
      z-index: 1;
    }

    .bt-generate {
      height: 38px;
      background-color: #667eea;
      border-radius: 12px;
      color: #ffffff;
      line-height: 0;
    }
  }
  .qr-result {
    position: relative;
    width: 132px;
    height: 132px;
    margin: 0 auto;
    transition: all 0.3s;
    img {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      height: auto;
      z-index: 1;
    }
  }
}qrcode-component.css

Finally

Then,Put everything together. ;)

QRcodeComponent

Demo

*Bonus, I add css animation for good UX, If you interest , can dowload following url ,thanks :)

Complete Code

Ok, Done for basic component ;)


Edit page
Share this post on:

Previous Post
Getting Started With Tree.js
Next Post
Hello, Web Components(1) — Basic component