Eliminate list items with a keyboard stroke

I am currently developing a straightforward todo list application using JavaScript.

The main functionality I am trying to implement is the ability to add new items from an input field to a list, as well as the option to remove items from the list.

While I have successfully created functions for storing input values and adding them to the list, I am facing difficulties with making the removal of elements work properly.

All necessary HTML, CSS, and JS code are provided. However, the removeItems() function seems to be malfunctioning.

const enterBtn = document.getElementById('enter');
const input = document.querySelector('input');
const ulList = document.querySelector('ul');
const delBtn = document.querySelector('button');

function inputLength() {
  return input.value.length;
}

// The following function adds delete buttons to existing list items
function addDelButtonsToExistingItems() {
  const liItems = document.querySelectorAll('li');
  for (let i = 0; i < liItems.length; i++) {
    const delBtn = document.createElement('button');
    delBtn.appendChild(document.createTextNode('delete'));
    liItems[i].appendChild(delBtn);
  }
}

// Add delete buttons to already existing items in the document
addDelButtonsToExistingItems();

// Function to add new items from the input field
function addNewItem() {
  if (inputLength() > 0) {
    const newLiItem = document.createElement('li');
    newLiItem.appendChild(document.createTextNode(input.value));
    const delBtn = document.createElement('button');
    delBtn.appendChild(document.createTextNode('delete'));
    newLiItem.appendChild(delBtn);
    ulList.appendChild(newLiItem);
    input.value = '';
  }
}

/**
* This function is intended to remove items from the list when the delete button is pressed
*/
function removeItems(e) {
  if (e.target.tagName === 'BUTTON') {
    e.target.classList.toggle('remove');
  }
}

/**
* Toggle the 'done' class on list items when clicked
*/
function toggleDone(e) {
  if (e.target.tagName === 'LI') {
    e.target.classList.toggle('done');
  }
}

// Handle the case where the enter key is pressed
function addOnEnterKeyPressed(e) {
  if (e.keyCode === 13) {
    addNewItem();
  }
}

// Event listener for adding new items when the enter button is clicked
enterBtn.addEventListener('click', addNewItem);

// Event listener to trigger adding new items when the enter key is pressed
input.addEventListener('keypress', addOnEnterKeyPressed);

// Event listener to toggle the 'done' class
ulList.addEventListener('click', toggleDone);

// Event listener to handle item removal upon clicking the delete button
// ???????
.done{
  text-decoration: line-through;
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="style.css">
    <title>Shopping List</title>
</head>

<body>
    <h1>Shopping List</h1>
    <h3>Get it done today</h3>
    <input type="text" name="input" id="input">
    <button id="enter">Enter</button>
    <ul>
        <li>NoteBook</li>
        <li>Pens</li>
        <li>Eraser</li>
        <li>CMPSC 412 book</li>
    </ul>
    <script src="script.js"></script>
</body>

</html>

Answer №1

Modified the code to remove some instances of const and streamlined the process for finding the target of the delete button click event.

Additionally, a new class delete has been included in the delete buttons to allow for more targeted selection without relying on tag names.

I have also added comments to highlight the code that has been altered.

const enterBtn = document.getElementById('enter');
const input = document.querySelector('input');
const ulList = document.querySelector('ul');

// Function to determine the length of input value
function inputLength() {
  return input.value.length;
}

function addDelButtonsToExistingItems() {
  const liItems = document.querySelectorAll('li');
  for (let i = 0; i < liItems.length; i++) {
    const delBtn = document.createElement('button');
    // A class has been added for easier targeting.
    delBtn.classList.add('delete');
    delBtn.appendChild(document.createTextNode('delete'));
    liItems[i].appendChild(delBtn);
  }
}

// Add delete buttons to existing items
addDelButtonsToExistingItems();

// Function to add new items from input field
function addNewItem() {
  if (inputLength() > 0) {
    const newLiItem = document.createElement('li');
    newLiItem.appendChild(document.createTextNode(input.value));
    const delBtn = document.createElement('button');
    // Another class has been added for easy identification.
    delBtn.classList.add('delete');
    delBtn.appendChild(document.createTextNode('delete'));
    newLiItem.appendChild(delBtn);
    ulList.appendChild(newLiItem);
    input.value = '';
  }
}

/**
 * Remove items from list when delete button is clicked by checking the document.
 */
function removeItem(e) {
  // Check if the target of the event has the 'delete' class and remove its parent li.
  if (e.target.classList.contains('delete')) {
    e.target.parentNode.remove();
  }
}

/**
 * Toggle 'done' class on list items when clicked
 */
function toggleDone(e) {
  if (e.target.tagName === 'LI') {
    e.target.classList.toggle('done');
  }
}

// When enter key is pressed
function addOnEnterKeyPressed(e) {
  if (e.keyCode === 13) {
    addNewItem();
  }
}

// Add new items on click of enter button
enterBtn.addEventListener('click', addNewItem);

// Add new items when enter key is pressed
input.addEventListener('keypress', addOnEnterKeyPressed);

// Toggle the 'done' class
ulList.addEventListener('click', toggleDone);

// Remove items when delete button is clicked. Targeting the document since delete elements can be updated.
document.addEventListener('click', removeItem);
.done {
  text-decoration: line-through;
}
<h1>Shopping List</h1>
<h3>Get it done today</h3>
<input type="text" name="input" id="input">
<button id="enter">Enter</button>
<ul>
  <li>NoteBook</li>
  <li>Pens</li>
  <li>Eraser</li>
  <li>CMPSC 412 book</li>
</ul>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieve the currently logged-in user whenever the component is rendered using React's Context API

For my small React project, I am utilizing ContextAPI. Whenever I hit the /login endpoint, I store the user's token using an HttpOnly Cookie. Below is the code for UserContext.js, which encapsulates all components (children) within App.js import axio ...

Check to see if the ContentEditable div is currently focused

I'm struggling to determine if a contenteditable div has focus with my current code. Here is what I have so far: if ($("#journal-content:focus")) { alert("Has Focus"); } else { alert("Doesn't Have Focus"); } The issue I'm encounter ...

Animating CSS when closing a modal box

I followed the instructions from a tutorial on W3Schools here to create this code. The "open model" button triggers the modal to open with a smooth CSS animation, which looks great. However, when I click the close button, the modal abruptly closes without ...

Menu options displayed with the help of HTML5 tags

Currently, I am experimenting with creating an interactive HTML5 dropdown menu in my spare time. While researching on W3Schools about dropdown menus, I noticed that all of them utilize CSS classes and id's for styling. This is a snippet of the HTML c ...

Moving a window in Pyqt5 using QtWebChannel

My goal is to enable the mousePressEvent and mouseMoveEvent events in order to move my app window using QtWebChannel. To achieve this, I am utilizing self.setWindowFlags(QtCore.Qt.FramelessWindowHint) to eliminate the default window flag and create a cust ...

Executing selenium tests on Internet Explorer 11 on a Windows 10 1809 machine without encountering any new pop-up windows

While testing on my computer, I encountered an issue where my test would start successfully, but after opening and closing several Internet Explorer windows during the test, no new windows would open. There were no error messages displayed, and the test se ...

What is the best way to extend the functionality of npm script with command line arguments

After defining multiple scripts in my package.json file, I encountered an issue when attempting to run the $ npm run lint:fix command. The argument --fix did not get passed down to ./node_modules/.bin/standard, resulting in an error. { "name": "project" ...

How come the likes are not being refreshed when the button is clicked in my mongoose schema?

I am currently working on an express app using nodejs and mongoose. My main goal is to implement a JavaScript function that can update the number of likes on a post in a database directly from my ejs file. However, I have encountered troubles with this tas ...

Show a nested array retrieved from JSON in a React component

I need assistance in displaying data from my JSON file, particularly an innested array using map(). The field I want to display as a list is analyzedInstructions, which looks like this: How to prep (from p How to prep /p) Steps: Remove the cauliflower&a ...

What is the best way to utilize multiple models under a single root in ReactJS?

Greetings! I currently have a root structure in the following code snippet: <body> <noscript>You need to enable JavaScript to run this app.</noscript> <button >Platform</button> <button >Game</button> < ...

Tips for keeping the DropDown Menu displayed even after moving the cursor away from the targeted element in Material-UI

import React from 'react'; import { makeStyles, Typography, Grid } from '@material-ui/core'; const styles = makeStyles((theme) => ({ root: {}, textStyle: { fontFamily: 'brandon-grotesque-black', tex ...

Tips for concealing validation errors in React Js when modifying the input field

I have recently started working with ReactJs, and I've implemented form validation using react-hook-form. After submitting the form, the errors are displayed correctly. However, the issue arises when I try to update the input fields as the error messa ...

Error: The function $scope.apply is invalid and cannot be executed

I am attempting to display the contacts list after retrieving it using rdflib.js. The data is being loaded and stored in the list within the scope. However, I am running into an issue where the $scope is not updating, and it appears that I may be calling ...

Tips for dividing HTML code on a page into individual nodes

I am looking to extract the HTML content from a website and then parse it into nodes. I attempted the following code: function load() { $(document).ready(function () { $.get("https://example.com/index.html", function (data) { const loadpage ...

Vue.js data does not exhibit reactivity

I am encountering an issue with a non-reactive data object nested inside another object in my Vue.js template. Here is the code snippet: <template> <div> <b-container class="bg-white text-center scrollBehavior" > ...

Generate a hyperlink within a paragraph

Can anyone provide tips on how to turn a string from Json into a paragraph with a hyperlink included? <p>Dumy Dumy Dumy Dumy Dumy Dumy Dumy DumyDumyDumyDumy abc.com </p> Currently, the paragraph displays as is, but I would like to make abc.c ...

Incorporating text overlays on images that are compatible with responsive websites is a top priority for me

This is a piece of HTML code that utilizes bootstrap 3 for design purposes. The challenge faced is related to positioning text over an image. When resizing the browser, the alignment of the text with the background gets disturbed. Assistance is needed in r ...

Compiling 'react-scripts' to include a few images as data URIs within the CSS file

I have recently inherited a sizable React project, even though my experience with React is limited. Nonetheless, I am attempting to make improvements in areas where I feel confident. An ongoing issue we are facing is the excessive size of our main CSS fil ...

Increase the spacing within div columns containing rows of uniform height

Is there a way to add some extra space between the H3-1 div and the H3-2 div? Ideally, I would like to achieve this without using custom CSS, but if necessary, that's okay too. I'd prefer to stick with the col-sm-6 class instead of using col-sm ...

How can I find the last element that was selected using XPath in the browser console

Need help with XPath: $x(("//div[@class='ag-header-row']))[1] I'm working with an array of divs, but I want to select the last one. The [1] is necessary due to multiple rows with this class. I’ve heard about using [last()], but unsure w ...