Delete the item along with its associated data from the local storage upon clicking on an icon

I'm currently working on a To-Do List and facing an issue while trying to delete an item upon clicking a trash bin icon.

image

The problem I'm encountering is that only one data point is removed from local storage when the icon is clicked. If I attempt to remove another 'li' tag, I have to refresh the page before it can be deleted.

My goal is to seamlessly remove both items and related data without the need for a page refresh. Any insights into what might be causing this issue would be greatly appreciated.

Thank you.

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>TO DO LIST</title>
    <link rel="stylesheet" href="style.css" />
    <link
      rel="stylesheet"
      href="https://use.fontawesome.com/releases/v5.13.1/css/all.css"
      integrity="sha384-xxzQGERXS00kBmZW/6qxqJPyxW3UR0BPsL4c8ILaIWXva5kFi7TxkIIaMiKtqV1Q"
      crossorigin="anonymous"
    />
    <script src="main.js" defer></script>
    <!-- <script src="data_storage.js" defer></script> -->
  </head>
  <body>
    <section class="container">
      <h1>TO DO LIST</h1>
      <ul></ul>
      <div class="footer">
        <input type="text" placeholder="Title..." />
        <button class="enter">Enter</button>
      </div>
    </section>
  </body>
</html>

CSS

* {
  font-family: Arial, Helvetica, sans-serif;
}

body {
  background-color: #ecf0f1;
}

.container {
  width: 50%;
  height: 100%;
  margin: auto;
  border: 1px solid green;
  border-radius: 15px 15px 0 0;
}

h1 {
  margin: 10px 20px;
  padding-bottom: 15px;
  text-align: center;
  font-size: 42px;
  color: #98e3a1;
  border-bottom: 1px dotted #5e7361;
}

ul {
  font-size: 24px;
  padding-bottom: 10px;
  list-style-type: none;
}

li {
  position: relative;
  padding-bottom: 8px;
  margin-bottom: 3px;
  margin-right: 20px;
  border-bottom: 1px solid grey;
}

.footer {
  display: block;
  position: relative;
}

input {
  position: relative;
  width: 93%;
  padding: 10px 0;
  border: none;
  outline: none;
}

.enter {
  position: absolute;
  padding: 0;
  width: 7%;
  height: 100%;
  outline: none;
  background-color: greenyellow;
  border: none;
  color: grey;
}

.fas {
  font-size: 20px;
  position: absolute;
  right: 10px;
  top: 10px;
  cursor: pointer;
  transition: transform 200ms ease-in;
}

.fas:hover {
  color: red;
  transform: scale(1.1);
}

JavaScript

const ul = document.querySelector("ul");
const input = document.querySelector("input");
const enterBtn = document.querySelector(".enter");

const LIST_LS = "lists";

function filterFn(toDo) {
  return toDo.id === 1;
}

let lists = [];

function saveStorage() {
  localStorage.setItem(LIST_LS, JSON.stringify(lists));
}

function deleteStorage(event) {
  const trashBtn = event.target;
  const li = trashBtn.parentNode;
  ul.removeChild(li);
  const cleanStorage = lists.filter((toDo) => {
    return toDo.id !== parseInt(li.id);
  });
  lists = cleanStorage;
  saveStorage();
}

function loadStorage() {
  const loadStorage = localStorage.getItem(LIST_LS);
  if (loadStorage !== null) {
    const parsedList = JSON.parse(loadStorage);
    parsedList.forEach((list) => {
      createItem(list.text);
    });
  }
}

function onAdd() {
  const text = input.value;
  if (text === "") {
    input.focus();
    return;
  }
  createItem(text);
  input.value = "";
  input.focus();
}

function createItem(text) {
  const itemRow = document.createElement("li");
  const newId = lists.length + 1;
  itemRow.setAttribute("class", "item__row");
  itemRow.innerHTML = `${text} <i class="fas fa-trash-alt" data-id=${itemRow.id}></i>`;

  ul.appendChild(itemRow);
  itemRow.id = newId;
  const delBtn = document.querySelector(".fa-trash-alt");
  delBtn.addEventListener("click", deleteStorage);

  const listObj = {
    text: text,
    id: newId,
  };

  lists.push(listObj);
  saveStorage();

  return itemRow;
}

loadStorage();

enterBtn.addEventListener("click", () => {
  onAdd();
});

input.addEventListener("keypress", (event) => {
  if (event.key === "Enter") onAdd();
});

Answer №1

The issue lies with this particular line of code:

const deleteButton = document.querySelector(".fa-trash-alt");

This means that it will consistently choose the first trash icon on the page. To resolve this, you should update it to:

const deleteButton = itemRow.querySelector(".fa-trash-alt");

You can see a working example by clicking on the link below:

https://codesandbox.io/s/damp-morning-csiny

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

When the fullscreen modal is opened, the initial image displayed is not the same as the one that was clicked on

Seeking assistance: I've been struggling with a problem for quite some time now and could really use some help from you guys. My issue involves an 'AngularJS' webapp that retrieves posts from an 'FB page' via 'OpenGraph' ...

Maintaining active navigation state in JQuery/JavaScript after clicking a link: tips and tricks

While many resources discuss adding the active class to a nav link using jquery, there is less information on maintaining the active state after the nav link has been clicked. After experimenting with code from various sources, I have attempted to set ses ...

How to properly align TableHeader and TableBody contents in a Material-UI table

I am experiencing an issue with a file that is supposed to display a table of data pulled from a database. Although the table does appear, all the data seems to be displayed under the ISSUE NUMBER column, instead of being aligned with their respective col ...

What is the best way to eliminate excess space on the right side in Bootstrap 4 while in mobile view?

I'm struggling to understand why this layout is not responsive on mobile devices, triggering a bottom scroll bar at around 616px. I'm looking for a solution to hide the scroll bar at least until 414px for iPhones and other smartphones. I've ...

The parent-child relationships in MongoDB

In my Meteor application, I have created two collections: ActivityCards and Users. Inside the ActivityCard collection, there is a reference to the User like this: { "_id" : "T9QwsHep3dMSRWNTK", "cardName" : "Guntnauna", "activitycardType" : 1 ...

Error: Attempting to create a Discord bot results in a TypeError because the property 'id' is undefined

While working on a basic Discord bot, I encountered an issue when running the -setcaps command. The error message I received was: TypeError: Cannot read property 'id' of undefined. I'm unsure about what might be causing this error. Any a ...

Safari's Web Audio API suffering from subpar performance and various shortcomings

For my University project, I am developing an HTML and JavaScript-based mp3 player using the Web Audio API. You can check out the progress of this project by visiting this link: While everything is running smoothly on Firefox and Chrome, Safari is posing ...

Shut down the active tab

For some reason, using window.close(); in my JavaScript script is not closing the currently opened tab as expected. I'm looking for a way to automatically close a manually opened tab using a JavaScript function. Any ideas on what might be going wrong? ...

Using a personalized function in JQuery

I need to execute a JavaScript function I created after a JQuery event has been triggered. The function in question is called scrambleDot, and I defined it previously like so:var scrambleDot = new function() { //my code }. Here's the attempted implem ...

The power of Rails unleashed through Ajax Remote Javascript

Trying to locate Employees who are engaged in multiple Job roles, I have set up three select boxes that dynamically adjust their options. The problem arises when my CoffeeScript file only triggers once. After the initial selection and rendering of the part ...

Having trouble resolving the dependency injection for stripe-angular

Attempting to integrate the stripe-angular module into my Ionic/AngularJS application. https://github.com/gtramontina/stripe-angular I have installed the module using npm install stripe-angular. This is how I include the dependency in my app: var myApp ...

Having trouble with localstorage.setitem function in Angular?

Check out the function below. I can see an object in the console.log using res: login2(){ console.log(this.user_form_value); console.log(this.password_form_value); this._loginService.login(this.user_form_value, this.password_form_value).subscr ...

Guide to displaying a component within the Vue instance

I am currently in the process of developing a Nuxt module that will not interfere with the main Nuxt application. My approach involves creating a separate Vue instance and mounting it as a child node under the body element, similar to a child node to the _ ...

Output the contents of a nested object

After setting up a variable containing music library data... var library = { tracks: { t01: { id: "t01", name: "Code Monkey", artist: "Jonathan Coulton", album: "Thing a Week Three" }, t02: { id: " ...

What are the best practices for managing promises effectively?

Currently, in my Angular application, I am utilizing $odataresource for handling data retrieval and updates. The code snippet I am working with is as follows: var measure = $odataresource("http://windows-10:8888/ChangeMeasure/"); var myMeasure = measure ...

Tips and tricks for seamlessly aligning a specific section of your webpage to ensure it scrolls smoothly into view

My codes are not being centered when I use smooth scrolling on a specific section of a Bootstrap carousel template. Is there an easier way to achieve this? The explanation in a post from six years ago didn't help much. Here are my codes and screenshot ...

Creating a dynamic circle that expands in size based on the duration the user presses down (using Java Script)

I have a fun challenge for you! I want to create a growing circle on a canvas based on how long you hold your mouse button. Currently, I can draw a fixed width circle where my mouse was when I clicked, but I need it to dynamically change size as you hold t ...

Troubleshooting jQuery.ajax - Why won't it function properly?

I've been struggling to get the ajax service functioning properly. I tried a simple $.get("http://google.com"), but it didn't work. Additionally, this code snippet failed as well: <html> <head> <script src="https://aja ...

In my React JS class component, I am looking to have the image display switch each time the button is clicked

How can I change the image when clicking a button in a class component? I am familiar with function components, but unsure how to achieve this. class CoffeeImages extends React.Component{ constructor(props){ super(props) ...

Problem arises with table nth-child selector following the addition of grid-gap

Our current table looks like this: The first row has a background color and the second row is white - which is correct. Now I would like to align the attributes to the right. I added the following code to the table: .table-wrapper tbody { font-size: ...