Home Posts Tags Post Search Tag Search

Post 23

Game Site Journal - 14 On-Screen Keyboard/Physical Integration

Published on: 2025-04-29 Tags: elixir, Blog, LiveView, Game Site, Html/CSS, Buttons, Clickable, Keyboard, Delete Button
For this post I wanted to go over the steps it took for me to be able to have a physical keyboard and the on screen keyboard work with each other. I already got rid of the extra line within Guess form that was taking care of the hidden cell that the :guess_string was being held in. 

<.input type="text" field={@form[:guess]} value={@guess_string} label="Guess" />

Once I set the value={@guess_string} I was able to be sure that the entry from keyboard or on-screen keyboard. This makes it so that yes we are passing the @form[:guess] to the form the @guess_string will be the default if we don't use the on-screen keyboard.

Now that we have that set I had to set some new hooks for the keyboard. This will listen for a "keydown" and be sure that it triggers the event for add_letter or delete_letter.

I will build the KeyInput function on a separate file under the path assets/js/hooks/KeyInputs.js 
# I had to create the hooks folder and KeyInputs.js file

let KeyInput = {
  mounted() {
    window.addEventListener("keydown", (e) => {
      if (/^[a-zA-Z]$/.test(e.key)) {
        this.pushEvent("add_letter", { letter: e.key.toLowerCase() });
      } else if (e.key === "Backspace") {
        this.pushEvent("delete_letter", {});
      }
    });
  },
  destroyed() {
    // Clean up event listener to avoid memory leaks
    window.removeEventListener("keydown", this.handleKeydown);
  }
};

export default KeyInput;

Once that was done navigate to assets/js/app.js

and be sure to add the needed lines. If you followed all the steps before you will have a few of these lines within the app.js already

// This might be one of 2 lines you need(below)
import KeyInput from "./hooks/KeyInput";

// ... existing imports
let Hooks = {};
// This might be one of 2 lines you need(below)
Hooks.KeyInput = KeyInput;

let liveSocket = new LiveSocket("/live", Socket, {
  hooks: Hooks
});
 

Once that was set you simple need to be sure to add the hook to the onscreen keyboard. I put it within the div for the entire on-screen keyboard.

<div class="space-y-1 sm:space-y-2 text-sm" phx-hook="KeyInput" id="keyboard">

That should be it.