Avoiding double entries in the shopping list using DOM selectors in JavaScript

I have been struggling with preventing duplicate items from being added to a shopping list that I created. Even though I thought the code below would solve the issue, it hasn't been effective so far. My expectation was for the JavaScript code to access the ul element and iterate through its list items in order to compare what is already on the list with the new item being added. I suspect the problem lies in accessing the input. Additionally, I am unsure about whether this functionality should be implemented within the createListElement function or the addListAfterClick function. Please refer to the provided code snippet to see how the code operates. Thank you in advance!!

var ul = document.getElementById("shoppingcart");
      var items = ul.getElementsByTagName("li");
      for (var i = 0; i < items.length; i++) {
        if (input.value === items[i]); {
          alert("already in list");
          console.log("already in list");


        }

var button = document.getElementById("enter");
var input = document.getElementById("userinput");
var ul = document.querySelector("ul");
var li = document.querySelectorAll("li");

function inputLength() {
  return input.value.length; // retrieves the length of the input value 

}

function createListElement() {
  var li = document.createElement("li"); // creates a new li element
  li.appendChild(document.createTextNode(input.value)); // adds the input value to the newly created li element
  li.classList.add("item"); // adds a class called "item" to the new li element
  li.addEventListener("click", toggleDone);
  /*  enables click functionality for the new item by referencing the toggleDone function, allowing toggling line-through 
                                              styling when an item on the list is clicked */

  ul.appendChild(li); // appends the li element in the ul element
  input.value = ""; // clears the input box for new inputs


  var button = document.createElement("button"); // creates a new button element
  button.appendChild(document.createTextNode("delete")); // creates a button labeled "delete"
  li.append(button); // adds a delete button next to each new input in the shopping list
  button.onclick = removeParent; // if the delete button is clicked, triggers the removeParent function to delete the input from the shopping list
}

function removeParent(event) {
  event.target.parentNode.remove(); // deletes an input from the parent node, which is the ul element, as remember li elements are children of ul elements
}

function toggleDone() {
  this.classList.toggle('done'); // references the CSS class ".done" for applying line-through styling, the toggle function switches the styling on and off
}

function addListAfterClick() {
  if (inputLength() > 0) // checks if the input length is greater than 0..(meaning an input is needed to add to the list)
  {
    createListElement(); // calls the createListElement function to add a new li element with the input value and a delete button alongside

  }

}

function addListAfterKeyPress(event) {
  if (inputLength() > 0 && event.keyCode === 13) // if input length is greater than 0 and enter key (key code 13) is pressed
  {
    {
      createListElement(); // calls createListElement function to add a new li element with the input value and a delete button alongside
    }

  }

}


button.addEventListener("click", addListAfterClick); 
input.addEventListener("keypress", addListAfterKeyPress);
<!DOCTYPE html>
<html>

<head>
  <title> JavaScript + DOM </title>

</head>

<body>
  <h1> Shopping List</h1>
  <p id="first"> Get it done today</p>
  <input id="userinput" type="text" placeholder="enter items">
  <button id="enter">Click Me!</button>

  <ul class="list" id="shoppingcart">
    <li class="bold red" random="23"> Notebook</li>

  </ul>

</body>

</html>

Answer №1

If you're looking for a quick fix, one approach is to utilize a "Set". With this data structure, checking for duplicates becomes a breeze. Here's an example:

var mySet = new Set();
mySet.add("apple");
mySet.add("banana");
mySet.has("apple"); // true
mySet.has("banana"); // true
mySet.has("cherry"); // false

You can integrate a set into your code by initializing it at the beginning and incorporating a has check within the addListAfterClick function:

function addListAfterClick() {
  if (inputLength() > 0 && !mySet.has(input.value))
  {
    createListElement();
  }

}

In the createListElement function, make sure to include the relevant value when creating a new list item:

function createListElement()
{
  // code...
  ul.appendChild(li);
  mySet.add(input.value);
  input.value = "";
  // code...
}

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

What is the method to verify if a pop-up browser window has completed its loading process?

There is a link on my website that opens a new window. However, sometimes the new window takes so long to load. To prevent users from clicking on the link before the new window finishes loading, I want to disable it until then. I am aware that one way to ...

Creating a Dynamic Layout with Varying Items in an Array Using PHP

Suppose I provide you with an array of objects, where x represents the number of objects. How would you achieve the following using a grid system (bootstrap, foundation, etc.)? Loop over the array and generate something similar to: https://i.sstatic.net/ ...

Using a color as a substitute for a background image on mobile devices

Is there a way to create a fallback in my CSS for changing the background image to a color when viewed on a mobile browser once the pixels reach the max-width? In the snippet below, the media query "only screen and (max-width: 600px)" works if the top bod ...

What is the best method to retrieve multiple values from a select dropdown and showcase them in an input field using ajax?

I am currently working on fetching multiple values from a database using AJAX and PHP. I have a select option which fetches values from the database, and when an option is selected, I want to display related data that matches the ID of the current option. ...

What causes an "Internal Server Error" when attempting to use data for a database request with AJAX GET/POST in Laravel?

There's a unique issue that I'm struggling to resolve... Every time I drag and drop an event into the calendar, an Ajax Post Request is sent to my controller. The controller then inserts some data into the database with the event name received v ...

I am currently studying JavaScript. The syntax of my if statement with && appears to be accurate, however

I'm having trouble with the logic in my "Code your Own Adventure" program on Code Academy. I expect it to display "Great, come get your pizza!" when I enter PIZZA, YES, and YES as prompts, but instead it says "NO pizza for you!" I've tried using ...

Divergent behavior of jQuery AJAX when used with a standard form versus when called in a popup within a div

Why does the jQuery AJAX work perfectly when submitting a form using the normal method, but not when submitting the same form within a popup? Below is the code for reference. Form submission script: $("#submit").click(function (e) { /* $('form&a ...

Extract specific elements from a webpage when conducting web scraping

Attempting to extract a table from a website using python, I successfully retrieved all the content within the table. However, being new to web scraping, I am unsure how to filter out only the elements I need. I have identified that I need to locate this ...

Persistent change issue with JQuery CSS function

Looking for some help with a button-bar div that I want to display only after the user clicks on a "settings" button. Currently, I have set the button-bar div to have a display:none property in my css file. However, when the settings button is clicked, t ...

Displaying specific data points

I am encountering an issue where I want to select multiple values and have each selected value displayed. However, when I make a selection, I only see one value from a single box. I do not wish to use append because it keeps adding onto the existing valu ...

Retrieve the customized attribute from the chosen option within the datalist

Is there a way to retrieve the custom attribute "location" of an option selected from a datalist and display it? I understand that for a select element we can use selectedIndex, but how can this be achieved with datalist? <!DOCTYPE html> <html&g ...

What is the best way to align a checkbox and text in the same row within a Mailchimp embedded form?

I am troubleshooting a styling issue with my Mailchimp form that has groups. The problem I'm encountering is that the checkboxes are displaying on one line while the text appears on the next line in an unordered list format. To see the issue for yours ...

Fancybox 2 - CSS styles vanish when using Ajax request

I have a fancybox2 with static dummy content that has styling applied. It works fine, but now I need to load dynamic content via ajax. However, when I make the ajax call, the required content loads but loses all css styling, most likely due to changes in t ...

What is the correct method for closing a style element in Nextjs JSX?

Having trouble adding some unique styling to a jsx component. The code snippet below is throwing an error when compiled. import Card from "./card"; export default function CardRow(){ return( <> <div> <Card> ...

What is the process for obtaining all of the options from a jQuery datepicker in order to create a new datepicker with identical settings?

Is there a way to easily replicate all options of a jQuery datepicker when creating a new instance? I am trying to duplicate a table that includes 2 datepickers with different settings. For reference, you can view an example here: http://jsfiddle.net/qwZ5 ...

Aligning the canvas resolution to match the video resolution for superimposition purposes

Within a div, I have both a canvas and a video element: <div id="videos"> <canvas id="my-canvas"></canvas> <video id="remote-video" autoplay></video> </div> Below is the css styling for both elements: #my-canv ...

How to Create Smooth Transitions for Text Arrays using jQuery's Fade In and Fade Out Features

I need to loop through an array of text and apply jQuery's fadeIn and fadeOut functions to each element. var greetings = ["hi, I'm", "bonjour, je m'appelle", "hallo, ich heiße"] The HTML structure I want is as follows: <h2><span ...

Closing a dropdown menu when opening another one

As a beginner in Vue.js, I am currently working on a CRUD project for my coursework. One issue I am facing is with the behavior of the dropdown menu. Can anyone provide assistance? https://i.sstatic.net/1MozuN3L.png I have specific requirements: The dr ...

Updating an href based on the presence of a variable in the URL

I've implemented an AMP layout where a unique code is added to the URL based on the traffic source. This code is used to update phone numbers displayed on the site. For instance, if you visit https://example.com/text?bid=1234 I created a script that ...

Erase Photo from Server by Simply Clicking on the Remove Button NodeJS (And Removing the Image Title from the Database)

I have a button that successfully deletes an image name from a mySQL table. However, I also want it to delete the actual image from the server. Below is the code snippet from my index.js: document.querySelector('table tbody').addEventListener(&a ...