JavaScript Keyboard

JavaScript Keyboard
Code Snippet:JavaScript - Virtual Keyboard
Author: Igor Agapov
Published: May 10, 2024
Last Updated: May 10, 2024
Downloads: 66
License: MIT
Edit Code online: View on CodePen
Read More

This JavaScript Keyboard code creates a virtual keyboard for text inputs. It appears when the input field is clicked, allowing easy typing. The keyboard includes standard keys like letters, numbers, and symbols. It also has special keys like backspace, enter, and caps lock, enhancing user typing experience. The keyboard’s appearance is customizable through CSS.

You can use this code on any website that requires text input fields. It enhances user experience by providing a virtual keyboard, making typing easier on touch devices. It’s beneficial for websites accessed on mobile devices or kiosks without physical keyboards.

How to Create a JavaScript Keyboard

1. First, load the following Google Fonts link into the head tag of your HTML document.

<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

2. Now, create an HTML file. Inside the <body> tag, add an input field where you want the virtual keyboard to appear.

<textarea class='keyboard-input'></textarea>

3. Add CSS styles to customize the appearance of the virtual keyboard. You can modify the styles according to your design preferences.

body {
  margin: 0;
  height: 100vh;
  background: radial-gradient(circle at top, skyblue, steelblue);
  overflow: hidden;
}

textarea {
  display: block;
  margin: 1em auto;
  padding: 0.4em;
  width: 90%;
  height: 30%;
  resize: none;
  font-size: 1.2em;
  font-family: system-ui, monospace;
  border-radius: 5px;
}

.keyboard {
  position: fixed;
  left: 0;
  bottom: 0;
  width: 100%;
  padding: 5px 0;
  background: #004134;
  box-shadow: 0 0 50px rgba(0, 0, 0, 0.5);
  user-select: none;
  transition: bottom 0.4s;
}

.keyboard-hidden {
  bottom: -100%;
}

.keyboard-keys {
  text-align: center;
}

.keyboard-key {
  height: 45px;
  width: 6%;
  max-width: 90px;
  margin: 3px;
  border-radius: 4px;
  border: none;
  background: rgba(255, 255, 255, 0.2);
  color: #fff;
  font-size: 1.05rem;
  outline: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: top;
  padding: 0;
  -webkit-tap-highlight-color: transparent;
  position: relative;
}

.keyboard-key:active {
  background: rgba(255, 255, 255, 0.12);
}

.keyboard-wide {
  width: 12%;
}

.keyboard-extrawide {
  width: 36%;
  max-width: 500px;
}

.keyboard-active::after {
  content: "";
  top: 10px;
  right: 10px;
  position: absolute;
  width: 8px;
  height: 8px;
  background: rgba(0, 0, 0, 0.4);
  border-radius: 50%;
}

.keyboard-check::after {
  background: #08ff00;
}

.keyboard-dark {
  background: rgba(0, 0, 0, 0.25);
}

4. Now, let’s add the JavaScript code to create the virtual keyboard functionality. Add the following script to your HTML file. This JavaScript code initializes the virtual keyboard and handles its functionality.

const Keyboard = {
  elements: {
    main: null,
    keysContainer: null,
    keys: []
  },

  eventHandlers: {
    oninput: null,
    onclose: null
  },

  properties: {
    value: "",
    capsLock: false
  },

  init() {
    this.elements.main = document.createElement("div");
    this.elements.keysContainer = document.createElement("div");

    this.elements.main.classList.add("keyboard", "keyboard-hidden");
    this.elements.keysContainer.classList.add("keyboard-keys");
    this.elements.keysContainer.appendChild(this._createKeys());

    this.elements.keys = this.elements.keysContainer.querySelectorAll(
      ".keyboard-key"
    );

    this.elements.main.appendChild(this.elements.keysContainer);
    document.body.appendChild(this.elements.main);

    document.querySelectorAll(".keyboard-input").forEach((element) => {
      element.addEventListener("focus", () => {
        this.open(element.value, (currentValue) => {
          element.value = currentValue;
        });
      });
    });
  },

  _createKeys() {
    const fragment = document.createDocumentFragment();
    const keyLayout = [
      "1",
      "2",
      "3",
      "4",
      "5",
      "6",
      "7",
      "8",
      "9",
      "0",
      "backspace",
      "q",
      "w",
      "e",
      "r",
      "t",
      "y",
      "u",
      "i",
      "o",
      "p",
      "caps",
      "a",
      "s",
      "d",
      "f",
      "g",
      "h",
      "j",
      "k",
      "l",
      "enter",
      "done",
      "z",
      "x",
      "c",
      "v",
      "b",
      "n",
      "m",
      ",",
      ".",
      "?",
      "space"
    ];

    const createIconHTML = (icon_name) => {
      return `<i class="material-icons">${icon_name}</i>`;
    };

    keyLayout.forEach((key) => {
      const keyElement = document.createElement("button");
      const insertLineBreak =
        ["backspace", "p", "enter", "?"].indexOf(key) !== -1;

      keyElement.classList.add("keyboard-key");

      switch (key) {
        case "backspace":
          keyElement.classList.add("keyboard-wide");
          keyElement.innerHTML = createIconHTML("backspace");
          keyElement.addEventListener("click", () => {
            this.properties.value = this.properties.value.substring(
              0,
              this.properties.value.length - 1
            );
            this._triggerEvent("oninput");
          });
          break;

        case "caps":
          keyElement.classList.add("keyboard-wide", "keyboard-active");
          keyElement.innerHTML = createIconHTML("keyboard_capslock");
          keyElement.addEventListener("click", () => {
            this._toggleCapsLock();
            keyElement.classList.toggle(
              "keyboard-check",
              this.properties.capsLock
            );
          });
          break;

        case "enter":
          keyElement.classList.add("keyboard-wide");
          keyElement.innerHTML = createIconHTML("keyboard_return");
          keyElement.addEventListener("click", () => {
            this.properties.value += "\n";
          });
          break;

        case "space":
          keyElement.classList.add("keyboard-extrawide");
          keyElement.innerHTML = createIconHTML("space_bar");
          keyElement.addEventListener("click", () => {
            this.properties.value += " ";
            this._triggerEvent("oninput");
          });
          break;

        case "done":
          keyElement.classList.add("keyboard-wide", "keyboard-dark");
          keyElement.innerHTML = createIconHTML("check_circle");
          keyElement.addEventListener("click", () => {
            this.close();
            this._triggerEvent("onclose");
          });
          break;
        default:
          keyElement.textContent = key.toLowerCase();
          keyElement.addEventListener("click", () => {
            this.properties.value += this.properties.capsLock
              ? key.toUpperCase()
              : key.toLowerCase();
            this._triggerEvent("oninput");
          });
          break;
      }

      fragment.appendChild(keyElement);

      if (insertLineBreak) {
        fragment.appendChild(document.createElement("br"));
      }
    });

    return fragment;
  },

  _triggerEvent(name) {
    if (typeof this.eventHandlers[name] === "function") {
      this.eventHandlers[name](this.properties.value);
    }
  },

  _toggleCapsLock() {
    this.properties.capsLock = !this.properties.capsLock;

    for (const key of this.elements.keys) {
      if (key.childElementCount === 0) {
        key.textContent = this.properties.capsLock
          ? key.textContent.toUpperCase()
          : key.textContent.toLowerCase();
      }
    }
  },

  open(initialValue, oninput, onclose) {
    this.properties.value = initialValue || "";
    this.eventHandlers.oninput = oninput;
    this.eventHandlers.onclose = onclose;
    this.elements.main.classList.remove("keyboard-hidden");
  },

  close() {
    this.properties.value = "";
    this.eventHandlers.oninput = oninput;
    this.eventHandlers.onclose = onclose;
    this.elements.main.classList.add("keyboard-hidden");
  }
};

Keyboard.init();

That’s all! hopefully, you have successfully created the virtual Keyboard. If you have any questions or suggestions, feel free to comment below.

Leave a Comment