To effectively delete the <li> element using JavaScript, make sure to eliminate the associated array object as well

I am in the process of designing a compact landing page that will randomly select a city from user input to determine the next trip destination. When the user types in the city name into the input field, everything functions correctly - a new list element is added to the ordered list and the name is included in an array for random selection later on. However, there seems to be an issue when trying to remove a city using the close function. The list element disappears as expected, but the wrong item is removed from the array (position 0 instead of the selected item). I'm currently troubleshooting this problem with my code. Below is the code I have written so far:

const submitBtn = document.querySelector(".addCity");
const cityList = document.querySelector(".city-ol");
let createdLi = document.getElementsByTagName("li");
const lis = document.querySelectorAll(".city-ol li");
let array = [];
submitBtn.addEventListener("click", newElement);


function newElement() {
  let li = document.createElement("li");
  let inputValue = document.querySelector(".inputTextField");
  let t = document.createTextNode(inputValue.value);
  li.appendChild(t);

  if (inputValue.value === "") {
    alert(
      "Please enter a city name before submitting."
    );
  } else {
    cityList.appendChild(li);
    array.push(inputValue.value);
    inputValue.value = "";
  }
  var span = document.createElement("SPAN");
  var txt = document.createTextNode("\u00D7");
  span.className = "close";
  span.appendChild(txt);
  li.appendChild(span);


  var close = document.getElementsByClassName("close");
  var i;
  for (i = 0; i < close.length; i++) {
    close[i].onclick = function() {
      let div = this.parentElement;
      div.style.display = "none";
      array.splice(close[i], 1);
    };
  };
};
body {
  font-family: "Poppins", sans-serif;
  height: 900px;
  text-align: center;
}

#landing-section {
  height: 100%;
}

.container {
  height: 100%;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(6, 1fr);
  gap: 5px;
  justify-content: center;
  align-content: center;
}

.header {
  grid-column: 1 / -1;
  border: 1px solid #000000;
}

.main-head {
  font-size: 3rem;
  text-transform: uppercase;
  margin-bottom: 0;
}

.main-para {
  font-size: 1.2rem;
  margin-top: 10px;
}

.cityInput {
  display: flex;
  justify-content: center;
  align-items: center;
  grid-column: 1 / 2;
  grid-row: 2 / 3;
  border: 1px solid #000000;
}

.inputTextField {
  width: 200px;
}

.cityList {
  display: flex;
  justify-content: center;
  align-items: center;
  grid-column: 1 / 2;
  grid-row: 3 / -1;
  width: 100%;
  border: 1px solid #000000;
}

.city-ol {
    font-size: 1.5rem;
    width: 100%;
}

.city-ol li:nth-child(odd) {
    background: #f9f9f9;
  }

li {
  margin: 5px 20px;
}

.close {
    position: relative;
    top: 3px;
    float: right;
  }
  
  .close:hover {
    background-color: #DCDCDC;
    color: white;
  }

.cityImage {
  grid-column: 2 / -1;
  grid-row: 2 / -1;
  border: 1px solid #000000;
}
<section id="landing-section">
  <div class="container">
    <div class="header">
      <h1 class="main-head">Make That Trip</h1>
      <p class="main-para">Are we ready to choose our next trip?</p>
    </div>
    <div class="cityInput">
      <input class="inputTextField" type="text" value="" data-type="city" placeholder="Enter city">
      <button class="addCity">Add</button>
    </div>
    <div class="cityList">
      <table>
        <ol class="city-ol">
        </ol>
      </table>

    </div>
    <div class="cityImage">City Image</div>
  </div>
</section>

Answer №1

There are 2 ways to address the issue FIX:

  1. When you add a new element, all 'close' elements in the DOM are added to close[]
Whenever an element is added to the DOM, it is audited during the add Element process
   let div = this.parentElement;
   div.style.display = "none"; 

FIX: Remove the element from the DOM
   let elm = this.parentElement;
   elm.remove();
  1. During loop execution, the variable i will increment as 1, 2, 3... but it may not be the same during function execution
FIX: Declare i using let 
   for (let i = 0; i < close.length; i++) {

Answer №2

With the assistance of your responses, I successfully identified and resolved the issue. Here is a breakdown of how I accomplished this:

  1. I extracted the text content from the list excluding the span, aligning it precisely with the array objects.

    let textNode = div.childNodes[0],
     text = textNode.textContent;
    
  2. Next, I matched the result of array.indexOf() with the previously isolated text, utilizing an if statement to trigger the array.splice() method if the index value is greater than -1.

    let index = array.indexOf(text);
     if (index > -1) {
       array.splice(index, 1);
     };
    

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

Adjust the form action and text input name according to the selected radio input

Seeking assistance with the following code, can someone help? $(document).ready(function() { $('#searchform').submit(function() { var action = ''; if($('.action_url').val() == 'l_catalog') { ...

Leverage jQuery to automatically submit an ajax form once all ajax requests have been successfully executed

I have integrated a WordPress plugin for store locator on my website. For pages without the interactive map, I have set up a form that serves as a location search tool. To clarify, the form includes a location field where users can input their desired loc ...

Individual Ajax data

Starting out with javascript, I'm a bit unsure of how to tackle this task. Essentially, I am looking to implement a for loop within the ajax data call, rather than listing each item manually. jQuery(document).ready(function() { ...

How can I implement a hover-over image change effect similar to the one seen in Gmail accounts?

I am attempting to implement a feature that allows users to change their image, similar to what can be done in a GMail account. When the user hovers over the image, an option to "change image" should appear. This may be a new concept for me because I am ...

Jquery Issue: Safari Leaves Alert Messages Unclosed When Opening Next Alert

I am experiencing an issue in Safari Browser and need some help with the following scenarios (with Example). When I click a button to delete an account, an alert message pops up. This alert window has two actions - "OK" and "Cancel". If I click "OK", it r ...

Optimal Strategy: Utilizing Spring Boot for Backend Development and jQuery for Frontend Interface

I am currently tackling a project that involves a Spring Boot 2 Backend and a jQuery Frontend. The frontend communicates with the backend by sending Ajax requests to Spring REST controllers in order to interact with database entities. One of the challenge ...

What could be causing the error "styled is not defined as a function" while creating my component library using Rollup?

Currently, I am facing an issue with my component library which is built using React, styled-components, framer-motion, Rollup, and Storybook. The library is being consumed by a NextJS website, but when trying to use it, I keep encountering the following e ...

What is the best way to assign a dictionary value to 'v-model' using a specific key?

Currently, I am working on integrating filterDataArray into my application to dynamically add parameters to my API requests. For this purpose, I have initialized the filterData array as follows: filterData: [ {key: 'name', value: '&ap ...

Connect with Friends - Using Express, MongoDB, and EJS for a Seamless Friend Connection

I have been working on creating a social network that allows users to send and interact with friend requests. Currently, I have completed the registration, log-in, and "search for other users" functions. Once I find and select another user, I am able to d ...

Is there a way to incorporate a computed value into a table prop while working with Element UI?

In my frontend development, I am utilizing vuejs along with element ui. I am faced with the task of rendering a table that includes dates in unix format. To make these dates more user-friendly, I have incorporated moment.js to convert them into a readable ...

Passing an ID via Link to retrieve data with getServerSideProps in Next.js

I have several alert components. From each of these components, I aim to pass the itm._id and receive it in [itm].jsx within the same folder. In [itm].jsx, I intend to utilize it in the getServerSideProps function for fetching data. Below is a snippet fro ...

Methods for sending data from Angular to the server and vice versa

Currently, I have an application that utilizes Express along with Jade templates. I am in the process of developing a new version of the app using Angular and client-side HTML. In order to determine user permissions within my Angular code, I require acces ...

Generate div elements dynamically for each object being populated in JSON using JavaScript

I have a main container that displays a list of JSON objects. Each object should be displayed as a separate DIV element with specific details, one after the other. Additionally, I have a comments section on a webpage where the details are stored in JSON f ...

Adjust image loading according to screen dimensions

I am working on HTML code that currently displays an image. The code looks like this: <div> <img id="wm01" alt="PP" title="PP" u="image" src="theImages/wm01.jpg" /> </div> My goal is to show a different image based on the screen si ...

Using Next Js for Google authentication with Strapi CMS

Recently, I've been working on implementing Google authentication in my Next.js and Strapi application. However, every time I attempt to do so, I encounter the following error: Error: This action with HTTP GET is not supported by NextAuth.js. The i ...

Collaborative JavaScript repository within the Websphere Liberty platform

Is it possible to utilize a JavaScript library (such as Dojo, JQuery, or other custom developed libraries) as shared libraries within a Websphere Liberty server? For instance, I am interested in storing the .js files in either C:\wlp\usr\sh ...

The process of running npm build is not resulting in the creation of the bundle.js file

I've read through many Q&A threads where people are facing the same issue, but I still can't figure out what's wrong with my code. When I run 'sudo npm run build', no bundle.js file is being created.** This is my code: index ...

React application experiencing issues with MQTT and Mosquitto broker connectivity

Upon installing the Mosquitto broker, I successfully tested it in my command prompt. However, when I attempted to establish a connection with my React application, I encountered the error message: "WebSocket connection to 'ws://localhost:1883/' f ...

Is it possible to set the state property in React js using the axios response?

After receiving data from axios, I am trying to store the response in a state value for rendering it in html. However, even though response.results displays the data when printed out, setting response.results in setState() results in an empty value. Here ...

Exploring Objects without the need for loops

Currently, I am focusing on optimizing the performance of the following objects: var scheduleFee = { poor = {level1:25,level2:25,level3:25} , good = {level1:15,level2:20,level3:25} , vgood = {level1:10,le ...