Search code examples
javascripthtmlcssbuttonkeyboard-events

What is the best way to make these buttons insert specific text into a text field?


I've made a virtual keyboard that has Russian characters and Latin characters. I want to make each character key on the virtual keyboard (.keyLetter) insert the Russian character (.primary) into the text field.
Additionally, I want to make each physical keyboard keypress activate the corresponding buttons onscreen, so that the user can type by clicking the onscreen keys, or by using their physical keyboard.
I want to print the character that is already written in the .primary div in order to avoid creating a unique function for every single key.
I'm very new to JavaScript, so please go easy on me. I'm just trying to find the best solution.
CodePen Link

const keyChar = document.getElementById('keyLetter')
keyChar.addEventListener('click', function() {
  //once the key is clicked, insert .primary of that key into the text box
  //but how to distinguish??
})
/*Body*/

h1 {
  margin: 3px;
  padding: 3px;
}

body {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  background: rgb(233, 188, 188)
}

#content {
  display: flex;
  justify-content: center;
  align-items: center;
}

#instructions {
  display: flex;
  flex-direction: column;
}

#instructions>h2 {
  margin: 2px;
  padding: 2px;
}

#instructions>p {
  margin: 3px;
  padding: 3px;
}

#inputTextWrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 10px;
  position: relative;
  top: 50px;
}

#instructions {
  width: 50%;
}

#inputTextField {
  width: 80%;
  min-width: 800px;
  max-width: 1000px;
  border-radius: 8px;
  border: none;
}

textarea#inputTextField {
  resize: none;
  min-height: 100px;
  height: auto;
  box-shadow: inset 0 0 3px black;
  padding: 1px;
}

.capsWarning {
  top: 50px;
  padding: 1px;
}


/* Keyboard */

button {
  padding: 0;
  margin: 1.5px;
  height: 45px;
  min-width: 22.5px;
  border-radius: 5px;
  border: none;
  background: rgba(255, 255, 255, 0.70)
}

button:active {
  background: rgba(255, 255, 255, 0.25);
}

button.keyLetter {
  width: 6%;
  max-width: 45px;
}

button.keyWide {
  width: 13%;
  max-width: 125px;
}

button.keyXWide {
  width: 45%;
  max-width: 400px;
}

.keyboardFooter {
  position: fixed;
  left: 0;
  bottom: 0;
  width: 100%;
  padding: 5px 0;
  background: rgb(238, 94, 94);
  box-shadow: 0 0 55px rgba(0, 0, 0, 0.5);
  user-select: none;
  transition: bottom 0.45s linear;
  height: 200px;
}

.keyboardHide {
  bottom: -100%;
}

.keyboardWrapper {
  display: flex;
  justify-content: center;
  width: 100%;
  height: 200px;
}

.keyboard {
  width: 90%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 4px;
}

.keyboardRow {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.buttonFlexWrapper {
  display: flex;
  width: 100%;
  justify-content: center;
  align-items: center;
}

.primary {
  display: flex;
  width: 75%;
  height: 45px;
  justify-content: center;
  align-items: center;
  font-size: large;
  font-weight: bold;
}

.secondary {
  display: flex;
  width: 25%;
  height: 45px;
  justify-content: flex-end | center;
  align-items: flex-end | center;
}


/* Mobile Overrides */

@media only screen and (max-width: 599px) {
  #content {
    flex-direction: row;
    flex-wrap: wrap;
  }
  #instructions,
  #inputText {
    width: 100%;
  }
  #inputTextField {
    width: 80%;
    min-width: 325px;
    max-width: 350px;
  }
  .keyboard {
    width: 100%;
  }
  .primary {
    justify-content: center;
    align-items: center;
  }
  .secondary {
    justify-content: left;
    align-items: left;
  }
}
<div class="keyboardFooter">
  <div class="keyboardWrapper">
    <div class="keyboard">
    
      <div id="row1" class="keyboardRow">
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Й</div>
                <div class="secondary">q</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Ц</div>
                <div class="secondary">w</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">У</div>
                <div class="secondary">e</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">К</div>
                <div class="secondary">r</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Е</div>
                <div class="secondary">t</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Н</div>
                <div class="secondary">y</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Г</div>
                <div class="secondary">u</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Ш</div>
                <div class="secondary">i</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Щ</div>
                <div class="secondary">o</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">З</div>
                <div class="secondary">p</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Х</div>
                <div class="secondary">[</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Ъ</div>
                <div class="secondary">]</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Ё</div>
                <div class="secondary">\</div>
            </div>
        </button>
      </div>
      
      <div id="row2" class="keyboardRow">
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Ф</div>
                <div class="secondary">a</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Ы</div>
                <div class="secondary">s</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">В</div>
                <div class="secondary">d</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">А</div>
                <div class="secondary">f</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">П</div>
                <div class="secondary">g</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Р</div>
                <div class="secondary">h</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">О</div>
                <div class="secondary">j</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Л</div>
                <div class="secondary">k</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Д</div>
                <div class="secondary">l</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Ж</div>
                <div class="secondary">;</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Э</div>
                <div class="secondary">'</div>
            </div>
        </button>
      </div>
      
      <div id="row3" class="keyboardRow">
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Я</div>
                <div class="secondary">z</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Ч</div>
                <div class="secondary">x</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">С</div>
                <div class="secondary">c</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">М</div>
                <div class="secondary">v</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">И</div>
                <div class="secondary">b</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Т</div>
                <div class="secondary">n</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Ь</div>
                <div class="secondary">m</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Б</div>
                <div class="secondary">,</div>
            </div>
        </button>
        <button type="button" class="key keyLetter">
            <div class="buttonFlexWrapper">
                <div class="primary">Ю</div>
                <div class="secondary">.</div>
            </div>
        </button>
        <button type="button" class="key keyWide"> 
            <i class="material-icons">backspace</i>
        </button>
      </div>
      
      <div id="row4" class="keyboardRow">
        <button type="button" class="key keyWide capsLock">
            <i class="material-icons">keyboard_capslock</i>
            <div class="keyLight"></div>
        </button>

        <button type="button" class="key keyXWide">
            <i class="material-icons">space_bar</i>
        </button>
      </div>
      
    </div>
  </div>
</div>


Solution

  • You do not have anything with id="keyLetter" - you have a class on each.

    You need to delegate.

    I implemented the capslock too

    I would personally not put divs in a button. Instead style the buttonFlexWrapper as a button

    const keyboard = document.querySelector('.keyboard');
    const output = document.getElementById("inputTextField");
    const capslock = document.querySelector(".capsLock");
    const capsWarning = document.querySelector(".capsWarning");
    capslock.addEventListener("click",function(e) {
      const tgt = e.target.closest("button");
      tgt.classList.toggle("active");
      capsWarning.classList.toggle("hide",!tgt.classList.contains("active"))
    })
    keyboard.addEventListener('click', function(e) {
      const tgt = e.target.closest(".keyLetter");
      if (tgt) {
        const primary = tgt.querySelector(".primary").textContent;
        const secondary = tgt.querySelector(".secondary").textContent;
        output.textContent += capsWarning.classList.contains("hide") ? primary :  secondary ;
      }
    })
    /*Body*/
    
    h1 {
      margin: 3px;
      padding: 3px;
    }
    
    body {
      display: flex;
      flex-direction: column;
      align-items: center;
      width: 100%;
      background: rgb(233, 188, 188)
    }
    
    #content {
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    #instructions {
      display: flex;
      flex-direction: column;
    }
    
    #instructions>h2 {
      margin: 2px;
      padding: 2px;
    }
    
    #instructions>p {
      margin: 3px;
      padding: 3px;
    }
    
    #inputTextWrapper {
      display: flex;
      justify-content: center;
      align-items: center;
      margin-top: 10px;
      position: relative;
      top: 50px;
    }
    
    #instructions {
      width: 50%;
    }
    
    #inputTextField {
      width: 80%;
      min-width: 800px;
      max-width: 1000px;
      border-radius: 8px;
      border: none;
    }
    
    textarea#inputTextField {
      resize: none;
      min-height: 100px;
      height: auto;
      box-shadow: inset 0 0 3px black;
      padding: 1px;
    }
    
    .capsWarning {
      top: 50px;
      padding: 1px;
    }
    
    
    /* Keyboard */
    
    button {
      padding: 0;
      margin: 1.5px;
      height: 45px;
      min-width: 22.5px;
      border-radius: 5px;
      border: none;
      background: rgba(255, 255, 255, 0.70)
    }
    
    button:active {
      background: rgba(255, 255, 255, 0.25);
    }
    
    button.keyLetter {
      width: 6%;
      max-width: 45px;
    }
    
    button.keyWide {
      width: 13%;
      max-width: 125px;
    }
    
    button.keyXWide {
      width: 45%;
      max-width: 400px;
    }
    
    .keyboardFooter {
      position: fixed;
      left: 0;
      bottom: 0;
      width: 100%;
      padding: 5px 0;
      background: rgb(238, 94, 94);
      box-shadow: 0 0 55px rgba(0, 0, 0, 0.5);
      user-select: none;
      transition: bottom 0.45s linear;
      height: 200px;
    }
    
    .keyboardHide {
      bottom: -100%;
    }
    
    .keyboardWrapper {
      display: flex;
      justify-content: center;
      width: 100%;
      height: 200px;
    }
    
    .keyboard {
      width: 90%;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      padding: 4px;
    }
    
    .keyboardRow {
      width: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    .buttonFlexWrapper {
      display: flex;
      width: 100%;
      justify-content: center;
      align-items: center;
    }
    
    .primary {
      display: flex;
      width: 75%;
      height: 45px;
      justify-content: center;
      align-items: center;
      font-size: large;
      font-weight: bold;
    }
    
    .secondary {
      display: flex;
      width: 25%;
      height: 45px;
      justify-content: flex-end | center;
      align-items: flex-end | center;
    }
    
    
    /* Mobile Overrides */
    
    @media only screen and (max-width: 599px) {
      #content {
        flex-direction: row;
        flex-wrap: wrap;
      }
      #instructions,
      #inputText {
        width: 100%;
      }
      #inputTextField {
        width: 80%;
        min-width: 325px;
        max-width: 350px;
      }
      .keyboard {
        width: 100%;
      }
      .primary {
        justify-content: center;
        align-items: center;
      }
      .secondary {
        justify-content: left;
        align-items: left;
      }
    }
    
    .hide { display: none; }
    <h1>Virtual Russian Keyboard</h1>
    
    <div id="inputTextWrapper">
      <textarea id="inputTextField" class="textBox"></textarea>
      <p class="capsWarning hide"><strong>CAPS Lock is on!</strong></p>
      <!--Broken Feature-->
    </div>
    
    <div class="keyboardFooter">
      <div class="keyboardWrapper">
        <div class="keyboard">
          <div id="row1" class="keyboardRow">
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Й</div>
                <div class="secondary">q</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Ц</div>
                <div class="secondary">w</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">У</div>
                <div class="secondary">e</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">К</div>
                <div class="secondary">r</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Е</div>
                <div class="secondary">t</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Н</div>
                <div class="secondary">y</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Г</div>
                <div class="secondary">u</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Ш</div>
                <div class="secondary">i</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Щ</div>
                <div class="secondary">o</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">З</div>
                <div class="secondary">p</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Х</div>
                <div class="secondary">[</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Ъ</div>
                <div class="secondary">]</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Ё</div>
                <div class="secondary">\</div>
              </div>
            </button>
          </div>
          <div id="row2" class="keyboardRow">
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Ф</div>
                <div class="secondary">a</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Ы</div>
                <div class="secondary">s</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">В</div>
                <div class="secondary">d</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">А</div>
                <div class="secondary">f</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">П</div>
                <div class="secondary">g</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Р</div>
                <div class="secondary">h</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">О</div>
                <div class="secondary">j</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Л</div>
                <div class="secondary">k</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Д</div>
                <div class="secondary">l</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Ж</div>
                <div class="secondary">;</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Э</div>
                <div class="secondary">'</div>
              </div>
            </button>
          </div>
          <div id="row3" class="keyboardRow">
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Я</div>
                <div class="secondary">z</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Ч</div>
                <div class="secondary">x</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">С</div>
                <div class="secondary">c</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">М</div>
                <div class="secondary">v</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">И</div>
                <div class="secondary">b</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Т</div>
                <div class="secondary">n</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Ь</div>
                <div class="secondary">m</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Б</div>
                <div class="secondary">,</div>
              </div>
            </button>
            <button type="button" class="key keyLetter">
              <div class="buttonFlexWrapper">
                <div class="primary">Ю</div>
                <div class="secondary">.</div>
              </div>
            </button>
            <button type="button" class="key keyWide"> 
              <i class="material-icons">backspace</i>
            </button>
          </div>
          <div id="row4" class="keyboardRow">
            <button type="button" class="key keyWide capsLock">
              <i class="material-icons">keyboard_capslock</i>
              <div class="keyLight"></div>
            </button>
            <button type="button" class="key keyXWide">
              <i class="material-icons">space_bar</i>
            </button>
          </div>
        </div>
      </div>
    </div>