Search code examples
javascriptfor-loopif-statementevent-listenerenter

How to invoke a function on pressing the "Enter" key


Here's the JSFiddle link to my app: https://jsfiddle.net/kdowdell24/a9t7b23c/2/

document.getElementById("add-button").addEventListener("click", function() {

function createNewItem() {
    //creates div element with a class of "input-item"
    let itemContainer = document.createElement("div");
    itemContainer.classList.add("input-item");

    //creates input element and sets type attribute to "checkbox"
    let checkBoxInput = document.createElement("input");
    checkBoxInput.setAttribute("type", "checkbox");
    checkBoxInput.classList.add("check-box");

    //creates input element and sets "type" attribute to "text"
    let textInput = document.createElement("input");
    textInput.setAttribute("type", "text");

    //creates button element and sets "class" to "delete-button" and "type" to "button"
    let deleteButton = document.createElement("button");
    deleteButton.classList.add("delete-button");
    deleteButton.setAttribute("type", "button");

    //creates Font Awesome "X" icon and adds "fas" and "fa-times" classes
    let xIcon = document.createElement("i");
    xIcon.classList.add("fas");
    xIcon.classList.add("fa-times");

    //adds a div to form
    let formElement = document.getElementById("shopping-list");
    formElement.appendChild(itemContainer);

    //adds checkbox, input, and "delete-button" to div
    itemContainer.appendChild(checkBoxInput);
    itemContainer.appendChild(textInput);
    itemContainer.appendChild(deleteButton);

    //adds "X" icon to button
    deleteButton.appendChild(xIcon);

    //removes checkbox, input and deleteButton from form
    deleteButton.addEventListener("click", function() {
        checkBoxInput.remove();
        textInput.remove();
        deleteButton.remove();
        itemContainer.remove();

    });
};

createNewItem();


//Adds new item after pressing Enter key
let itemList = document.querySelectorAll("input[type=text]");
for (var i = 0; i < itemList.length; i++) {
    addEventListener("keypress", function(e) {
        if (e.key === "Enter") {
            createNewItem();
            console.log("New item created!");
        }
    })
}

});

//Removes all content from list after pressing Clear All button
document.getElementById("clear-button").addEventListener("click", function() {
let listContent = document.querySelectorAll(".input-item");
for (var i = 0; i < listContent.length; i++) {
    listContent[i].remove();
}

})

The issue I'm having is with this block of code:

//Adds new item after pressing Enter key
let itemList = document.querySelectorAll("input[type=text]");
for (var i = 0; i < itemList.length; i++) {
    addEventListener("keypress", function(e) {
        if (e.key === "Enter") {
            createNewItem();
            console.log("New item created!");
        }
    })
}

What's happening is that when I press Enter while in the textbox of a list item it adds multiple entries instead of just one. What I'm trying to accomplish is to have only one item entry created below the current one after hitting Enter.


Solution

  • If you want to add a new checkbox when the ENTER key is pressed, just change this:

    let itemList = document.querySelectorAll("input[type=text]");
    for (var i = 0; i < itemList.length; i++) {
        addEventListener("keypress", function(e) {
            if (e.key === "Enter") {
                createNewItem();
                console.log("New item created!");
            }
        })
    }
    

    To this:

    document.addEventListener("keypress", function(e) {
      if (e.key === "Enter" && (document.activeElement.tagName.toLowerCase() !== 'button')) {
        createNewItem();
        console.log("New item created!");
      }
    });
    

    I forked your current jsFiddle and used the above code instead here: https://jsfiddle.net/AndrewL64/3fcgpxrL/30/

    Credits to @Moosecouture who mentioned the use of document.activeElement to prevent unwanted invokes when an element is in focus during the keypress.