Search code examples
javascriptstringvirtual-keyboard

Restrict virtual keyboard Input to input field maxLength JavaScript


My problem is: how to limit the length of characters from virtual keyboard. I found a virtual keyboard on codepen https://codepen.io/dcode-software/pen/KYYKxP and I would like to restrict input characters to input field maxLength. Can someone help? This is my approach, would like to last character not changing after input.

keyElement.addEventListener("click", () => {
  var element = document.querySelectorAll(".use-keyboard-input");
  element.maxLength = 10;
  if (this.properties.value.length === element.maxLength) {
    this.properties.value = this.properties.value.substring(0, this.properties.value.length - 1);
    this._triggerEvent("oninput");
  }
});

Solution

  • Unfortunately that's the wrong approach to this issue. First lets look at the problems that your approach will cause:

    1. keyElement.addEventListener("click", () => {
      This will trigger on each key click event. You don't want that because you still want the backspace key to work if the maxLength is reached.
    2. if(this.properties.value.length === element.maxLength){
      This will only trigger if the value of the input field is exactly the same length as the maxLength property. If the user somehow bypasses it, it'll no longer have any effect. A better solution would be to use >= instead of ===.
    3. this.properties.value = this.properties.value.substring(0, this.properties.value.length-1 );
      This is your actual problem. It'll replace the last character value. Instead, you should simply return false;

    Now lets look on how to get this to work properly:

    First you'll want to make the maxLength property available to you. In order to do this, you need to change the following.

    properties: {
        value: "",
        capsLock: false, // Add a comma here
        maxLength: 0 // Add this line
    },
    
    document.querySelectorAll(".use-keyboard-input").forEach(element => {
        element.addEventListener("focus", () => {
            this.open(element.value, element.maxLength, currentValue => { // Pass element.maxLength as a parameter
                element.value = currentValue;
            });
        });
    });
    
    open(initialValue, maxlength, oninput, onclose) { // Add maxlength parameter
        this.properties.value = initialValue || "";
        this.properties.maxLength = maxlength; // Set the property value
        this.eventHandlers.oninput = oninput;
        this.eventHandlers.onclose = onclose;
        this.elements.main.classList.remove("keyboard--hidden");
    },
    

    Next you need to go through each button's event handler and add a conditional to it. I'll give you an example here, you can do all the others yourself as it's just the same.

    case "enter":
        keyElement.classList.add("keyboard__key--wide");
        keyElement.innerHTML = createIconHTML("keyboard_return");
    
        keyElement.addEventListener("click", () => {
    
            // Check if the length of the value is equal or bigger than maxLength
            if(this.properties.value.length >= this.properties.maxLength){
                // Return false so it doesn't do anything
                return false;
            }
            this.properties.value += "\n";
            this._triggerEvent("oninput");
        });
    
        break;
    

    Just make sure you don't add that to keys that you still want to function in case maxLength is reached.