Using submit button and enter key to add to-do-list

Viewed 56

I am doing a simple to-do list to keep learning JS and so far I have two issues that I can't solve, I would like to know if you guys could help me.

First, I would like to use the button and the enter key to add a task instead of just pressing enter, I know I could use a form and the preventDefault(); method but I would like to explore other options, I can make it work by changing the event listener to 'click' since the button is a submit type but then the text won't add when pressing enter.

Second, the "There are no pending tasks." message div shows up at the beginning when no tasks are added and disappear when a task is added, so far its ok but when I delete all the tasks the message won't show up again, maybe my logic is failing somehow but can't figure it out where.

let board = document.querySelector('.to-do-board');
let taskContainer = document.querySelector('.container-task');
let taskbar = document.querySelector('.add-task');
let button = document.querySelector('.add-btn');
let noTasksMsg = document.querySelector('.message');


taskbar.addEventListener('keypress', (e) => {
    if (e.key === 'Enter' && taskbar.value !== '') {
    
        if (taskContainer === null) {
            noTasksMsg.style.display = 'flex';
        } else {
            noTasksMsg.style.display = 'none';
        }

        let div = document.createElement('div');
        div.className = 'item-task';
        div.innerHTML = taskbar.value;
        taskContainer.insertAdjacentElement('beforeend', div)

        let deleteButton = document.createElement('button')
        deleteButton.className = 'deleteBtn';
        deleteButton.textContent = "X";
        div.appendChild(deleteButton);

        taskbar.value = '';

        deleteButton.addEventListener('click', () => {
            div.remove();
        })
    }
})
*, *:before, *:after {
    box-sizing: border-box;
    margin: 0;
    letter-spacing: 2px;
  }

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: 15px;
}

.to-do-board {
    width: 500px;
    background: #88CCF1;
    border-radius: 10px;
}

.title {
    background: #3587A4;
    border-top-right-radius: 10px;
    border-top-left-radius: 10px;
}

h1 {
    text-align: center;
    color: white;
    padding: .5em 0 .5em 0;
    font-size: 22px;
}

.inputs {
    display: flex;
    justify-content: center;
    margin: 1em;
}

.add-task {
    padding: .5em;
    width: 80%;
    margin-right: 1em;
}

.add-btn {
    padding: 0 1em 0 1em;
    font-size: large;
    font-weight: bolder;
    color: white;
    border: none;
    border-radius: 10px;
    background: #2D848A;
    cursor: pointer;
}

.add-btn:hover {
    background: #3587A4;
}

.container-task {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 1em;
}

.item-task {
    display: flex;
    justify-content: space-between;
    background: #C1DFF0;
    width: 90%;
    border-radius: 10px;
    margin-bottom: 10px;
}

.deleteBtn {
    border: none;
    background: #d45151;
    width: 3em;
    border-top-right-radius: 10px;
    border-bottom-right-radius: 10px;
    height: 2.5em;
    color: white;
    font-weight: bold;
    cursor: pointer;
}

.deleteBtn:hover {
    background: rgb(235, 95, 95);
}

.message {
    text-align: center;
    padding: 1em;
    color: white;
    background: #63afb1;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" lang="en">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="styles.css">
    <script src="main.js" defer></script>
    <title>To-do List!</title>
</head>
<body>
    <div class="container">
        <div class="to-do-board">
            <div class="title"><h1>To-Do List!</h1></div>
            <div class="inputs">
                <input type="text" placeholder="Add a task" class="add-task">
                <input type="submit" value="+" class="add-btn">
            </div>
            <div class="container-task">
                <div class="message">There are no pending tasks.</div>
            </div>
        </div>
    </div>
</body>
</html>

Thank you very much.

1 Answers

You can extract the code inside your eventListener to a separate function, pass it the event object and slightly modify it to check if e.type is click in addition to checking for the enter key but I'd still recommend against it and recommend using <form>.

let board = document.querySelector('.to-do-board');
let taskContainer = document.querySelector('.container-task');
let taskbar = document.querySelector('.add-task');
let button = document.querySelector('.add-btn');


taskbar.addEventListener('keypress', handleEvent)
button.addEventListener('click', handleEvent)

function handleEvent(e){
   if ((e.type === 'click' || e.key === 'Enter') && taskbar.value !== '') {

        if(taskContainer.querySelector(".message") != null){
            taskContainer.querySelector(".message").remove()
        }
        let div = document.createElement('div');
        div.className = 'item-task';
        div.innerHTML = taskbar.value;
        taskContainer.appendChild(div)

        let deleteButton = document.createElement('button')
        deleteButton.className = 'deleteBtn';
        deleteButton.textContent = "X";
        div.appendChild(deleteButton);

        taskbar.value = '';

        deleteButton.addEventListener('click', () => {
            div.remove();
            if(taskContainer.children.length == 0){
                const message = document.createElement("div")
                message.classList.add("message")
                message.textContent = "There are no pending tasks."
                taskContainer.appendChild(message);
            }
        })
    }
}

   
*, *:before, *:after {
    box-sizing: border-box;
    margin: 0;
    letter-spacing: 2px;
  }

.container {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: 15px;
}

.to-do-board {
    width: 500px;
    background: #88CCF1;
    border-radius: 10px;
}

.title {
    background: #3587A4;
    border-top-right-radius: 10px;
    border-top-left-radius: 10px;
}

h1 {
    text-align: center;
    color: white;
    padding: .5em 0 .5em 0;
    font-size: 22px;
}

.inputs {
    display: flex;
    justify-content: center;
    margin: 1em;
}

.add-task {
    padding: .5em;
    width: 80%;
    margin-right: 1em;
}

.add-btn {
    padding: 0 1em 0 1em;
    font-size: large;
    font-weight: bolder;
    color: white;
    border: none;
    border-radius: 10px;
    background: #2D848A;
    cursor: pointer;
}

.add-btn:hover {
    background: #3587A4;
}

.container-task {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 1em;
}

.item-task {
    display: flex;
    justify-content: space-between;
    background: #C1DFF0;
    width: 90%;
    border-radius: 10px;
    margin-bottom: 10px;
}

.deleteBtn {
    border: none;
    background: #d45151;
    width: 3em;
    border-top-right-radius: 10px;
    border-bottom-right-radius: 10px;
    height: 2.5em;
    color: white;
    font-weight: bold;
    cursor: pointer;
}

.deleteBtn:hover {
    background: rgb(235, 95, 95);
}

.message {
    text-align: center;
    padding: 1em;
    color: white;
    background: #63afb1;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" lang="en">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="styles.css">
    <script src="main.js" defer></script>
    <title>To-do List!</title>
</head>
<body>
    <div class="container">
        <div class="to-do-board">
            <div class="title"><h1>To-Do List!</h1></div>
            <div class="inputs">
                <input type="text" placeholder="Add a task" class="add-task">
                <input type="submit" value="+" class="add-btn">
            </div>
            <div class="container-task">
               <div class="message">
                  You have not added any tasks.
               </div>
            </div>
        </div>
    </div>
</body>
</html>

Related