the else/if statement executes only on the first run

In my current code, when the user inputs a color that matches any of the colors in the array, it will add that color class to the main div.

The issue I'm facing is that my else-if statements only run once. If you input the same color again, it won't add that class after running a different color (e.g. black > red > black).

Is there a more efficient way to handle this scenario?

'use strict';

let inputElement = document.getElementById('inpp');
const btn = document.getElementById('btn');
let outputValue = document.getElementById('output');
const bodyEl = document.getElementById('thisBody');

btn.addEventListener('click', (e) => {
    // Prevent form from reloading page
    e.preventDefault();
  
  let inputValue = inputElement.value;
  
  let favColors = [
    'black',
    'red',
    'blue',
    'green',
    'yellow',
    'pink',
    'orange',
    'brown',
    'white',
    'purple'
  ];
  
  // Handle user input match
  if (favColors.includes(inputValue)) {
    outputValue.innerHTML = `Awesome choice! ${inputValue} is a great color!`;
  } else if (inputValue === '') {
    outputValue.innerHTML = `Please enter a color.`;
  } else {
    outputValue.innerHTML = `Interesting! ${inputValue} is not on my list of favorites.`;
  }

  // Add color classes based on user input
  for(let i=0; i < favColors.length; i++) {
    if(favColors[i] === inputValue) {
      bodyEl.classList.add(favColors[i]);
      break;
    }
  }
  
  // Clear input value
  inputElement.value = '';
});
/* Color classes */
.black {
  background-color: black !important;
}

.red {
  background-color: red !important;
}

.blue {
  background-color: blue !important;
}

.green {
  background-color: green !important;
}

.yellow {
  background-color: yellow !important;
}

.pink {
  background-color: pink !important;
}

.orange {
  background-color: orange !important;
}

.brown {
  background-color: brown !important;
}

.white {
  background-color: white !important;
}

.purple {
  background-color: purple !important;
}
<div id="thisBody">
  <div class="container">
    <div class="content">
      <div>
        <h1 id="output">What's your favorite color?</h1>
        <form id="formy">
          <input id="inpp" type="text" placeholder="What's your favorite color?">
          <button type="submit" id="btn">Submit</button>
        </form>
      </div>
    </div>
  </div>
 </div>

Answer №1

Initially, your code can undergo a significant reduction:

  if(favColors.includes(inputValue)) bodyEl.classList.add(inputValue);

The main problem you are encountering is the double addition to the classList. To resolve this issue, simply clear all favorite colors before adding:

  if(favColors.includes(inputValue)) {
    bodyEl.classList.remove(...favColors);
    bodyEl.classList.add(inputValue);
  }

Update:

If you actually want to layer the classes on top of each other (although I doubt that's your intention), you could try the following approach:

  if(favColors.includes(inputValue)) {
    bodyEl.classList.remove(inputValue);
    bodyEl.classList.add(inputValue);
  }

Answer №2

To update the color, it is necessary to eliminate the existing color first. The array can be utilized for verification as well.

'use strict';

let inputElement = document.getElementById('inpp');
const btn = document.getElementById('btn');
let outputValue = document.getElementById('output');
const bodyEl = document.getElementById('thisBody');
let lastColor;

btn.addEventListener('click', (e) => {
    // Avoid form from refreshing page
    e.preventDefault();
  
  let inputValue = inputElement.value;
  
  let favColors = ['black', 'red', 'blue', 'green', 'yellow', 'pink', 'orange', 'brown', 'white', 'purple'];
  
  // Check if user input matches any color in the array
  if (favColors.includes(inputValue)) {
    outputValue.innerHTML = `Nice choice! ${inputValue} is a great color.`;
  } else if (inputValue === '') {
    outputValue.innerHTML = `Please specify a color..`;
  } else {
    outputValue.innerHTML = `That's interesting, ${inputValue} is unfamiliar to me!`;
  }

  // Apply color classes when there's a match
  if (favColors.includes(inputValue)) {
      if (lastColor) bodyEl.classList.remove(lastColor);
      bodyEl.classList.add(inputValue);
      lastColor = inputValue;
  }
  
  // Clear input field after submission
  inputElement.value = '';
});
.black { background-color: black !important; }
.red { background-color: red !important; }
.blue { background-color: blue !important; }
.green { background-color: green !important; }
.yellow { background-color: yellow !important; }
.pink { background-color: pink !important; }
.orange { background-color: orange !important; }
.brown { background-color: brown !important; }
.white { background-color: white !important; }
.purple { background-color: purple !important; }
<div id="thisBody">
  <div class="container">
    <div class="content>
      <div>
        <h1 id="output">What's your favorite color?</h1>
        <form id="formy">
          <input id="inpp" type="text" placeholder="What's your favorite color?">
          <button type="submit" id="btn">Submit</button>
        </form>
      </div>
    </div>
  </div>
 </div>

Answer №3

Your ifs execute multiple times, but you are only adding new color classes without clearing the old ones. To clear them, include this code before your ifs:

bodyEl.className = "";

Demo:

'use strict';

let inputElement = document.getElementById('inpp');
const btn = document.getElementById('btn');
let outputValue = document.getElementById('output');
const bodyEl = document.getElementById('thisBody');

btn.addEventListener('click', (e) => {
    // Prevent form from reloading page
    e.preventDefault();
  
  let inputValue = inputElement.value;
  
  let favColors = [
    'black',
    'red',
    'blue',
    'green',
    'yellow',
    'pink',
    'orange',
    'brown',
    'white',
    'purple'
  ];
  
  // If user input match
  if (favColors.includes(inputValue)) {
    outputValue.innerHTML = `Awesome, ${inputValue} is so neat!`;
  } else if (inputValue === '') {
    outputValue.innerHTML = `Please enter a color..`;
  } else {
    outputValue.innerHTML = `Interesting, ${inputValue} is new to me!`;
  }
  
  // remove previous color
  bodyEl.className = "";

  // Add color classes on match
  if (favColors[0] === inputValue) {
    bodyEl.classList.add('black');
  } else if (favColors[1] === inputValue) {
    bodyEl.classList.add('red');
  } else if (favColors[2] === inputValue) {
    bodyEl.classList.add('blue');
  } else if (favColors[3] === inputValue) {
    bodyEl.classList.add('green');
  } else if (favColors[4] === inputValue) {
    bodyEl.classList.add('yellow');
  } else if (favColors[5] === inputValue) {
    bodyEl.classList.add('pink');
  } else if (favColors[6] === inputValue) {
    bodyEl.classList.add('orange');
  } else if (favColors[7] === inputValue) {
    bodyEl.classList.add('brown');
  } else if (favColors[8] === inputValue) {
    bodyEl.classList.add('white');
  } else if (favColors[9] === inputValue) {
    bodyEl.classList.add('purple');
  } 
  
  // Clear input value
  inputElement.value = '';
});
/* Color classes */
.black {
  background-color: black !important;
}

.red {
  background-color: red !important;
}

.blue {
  background-color: blue !important;
}

.green {
  background-color: green !important;
}

.yellow {
  background-color: yellow !important;
}

.pink {
  background-color: pink !important;
}

.orange {
  background-color: orange !important;
}

.brown {
  background-color: brown !important;
}

.white {
  background-color: white !important;
}

.purple {
  background-color: purple !important;
}
<div id="thisBody">
  <div class="container">
    <div class="content">
      <div>
        <h1 id="output">What's your favorite color?</h1>
        <form id="formy">
          <input id="inpp" type="text" placeholder="What's your favorite color?">
          <button type="submit" id="btn">Submit</button>
        </form>
      </div>
    </div>
  </div>
 </div>

For a more effective approach, refer to @mplungjan's Answer

Answer №4

Make sure to update the color when it's found

Prior to setting the new color, save and remove the old one

Consider changing the color to white if the background color is black

let savedColor = "";
 ...


if (favColors.includes(inputValue)) {
  outputValue.innerHTML = `Great choice! ${inputValue} looks fantastic!`;
  if (savedColor) bodyEl.classList.remove(savedColor);
  bodyEl.classList.add(inputValue);
  savedColor = inputValue;
  bodyEl.style.color = inputValue === "black" ? "white" : "black"
}

'use strict';

const favColors = ['black', 'red', 'blue', 'green', 'yellow', 'pink', 'orange', 'brown', 'white', 'purple'];

let savedColor = "";
let inputElement = document.getElementById('inpp');
const btn = document.getElementById('btn');
let outputValue = document.getElementById('output');
const bodyEl = document.getElementById('thisBody');

btn.addEventListener('click', (e) => {
  // Prevent form from reloading page
  e.preventDefault();

  let inputValue = inputElement.value;

  // If user input match
  if (favColors.includes(inputValue)) {
    outputValue.innerHTML = `Great choice! ${inputValue} looks fantastic!`;
    if (savedColor) bodyEl.classList.remove(savedColor);
    bodyEl.classList.add(inputValue);
    savedColor = inputValue;
    bodyEl.style.color = inputValue === "black" ? "white" : "black"
  } else if (inputValue === '') {
    outputValue.innerHTML = `Please enter a color..`;
  } else {
    outputValue.innerHTML = `Interesting, ${inputValue} is new to me!`;
  }

  // Clear input value
  inputElement.value = '';
});
/* Color classes */

.black {
  background-color: black !important;
}

.red {
  background-color: red !important;
}

.blue {
  background-color: blue !important;
}

.green {
  background-color: green !important;
}

.yellow {
  background-color: yellow !important;
}

.pink {
  background-color: pink !important;
}

.orange {
  background-color: orange !important;
}

.brown {
  background-color: brown !important;
}

.white {
  background-color: white !important;
}

.purple {
  background-color: purple !important;
}
<div id="thisBody">
  <div class="container">
    <div class="content">
      <div>
        <h1 id="output">What's your favorite color?</h1>
        <form id="formy">
          <input id="inpp" type="text" placeholder="What's your favorite color?">
          <button type="submit" id="btn">Submit</button>
        </form>
      </div>
    </div>
  </div>
</div>

Answer №5

You may notice that when adding classes based on the color, they are never removed. This means that as you continue to add classes, only the last one will be considered. For example, if you have a class of "pink purple", it will ignore "pink".

'use strict';

let inputElement = document.getElementById('inpp');
const btn = document.getElementById('btn');
let outputValue = document.getElementById('output');
const bodyEl = document.getElementById('thisBody');

btn.addEventListener('click', (e) => {
  // Prevent form from reloading page
  e.preventDefault();

  let inputValue = inputElement.value.toLowerCase(); // so "Black", "black" and "BLACK" will all work

  let favColors = [
    'black',
    'red',
    'blue',
    'green',
    'yellow',
    'pink',
    'orange',
    'brown',
    'white',
    'purple'
  ];

  // If user input match
  if (favColors.includes(inputValue)) {
    outputValue.innerHTML = `Awesome, ${inputValue} is so neat!`;

    // Add color classes on match (no need to have a separate `if`)
    // remove any previously set color: the reason for looping through `favColors`
    // is to preserve any class not related to color that you might have on the element
    favColors.forEach(color => bodyEl.classList.remove(color));
    // add the new color
    bodyEl.classList.add(inputValue);
  } else if (inputValue === '') {
    outputValue.innerHTML = `Please enter a color..`;
  } else {
    outputValue.innerHTML = `Interesting, ${inputValue} is new to me!`;
  }

  // Clear input value
  inputElement.value = '';
});
/* Color classes */

.black {
  background-color: black !important;
  color: white;
}

.red {
  background-color: red !important;
}

.blue {
  background-color: blue !important;
}

.green {
  background-color: green !important;
}

.yellow {
  background-color: yellow !important;
}

.pink {
  background-color: pink !important;
}

.orange {
  background-color: orange !important;
}

.brown {
  background-color: brown !important;
}

.white {
  background-color: white !important;
}

.purple {
  background-color: purple !important;
}
<div id="thisBody">
  <div class="container">
    <div class="content">
      <div>
        <h1 id="output">What's your favorite color?</h1>
        <form id="formy">
          <input id="inpp" type="text" placeholder="What's your favorite color?">
          <button type="submit" id="btn">Submit</button>
        </form>
      </div>
    </div>
  </div>
</div>

P.S. I also made some optimizations in your code and added comments for clarification.

Answer №6

The Element.classList interface in the DOMTokenList is a collection of tokens separated by spaces.

Sets may resemble arrays, but each value within a set is unique and duplicates cannot be added.

Furthermore, attempting to add the same class multiple times to an element will not result in any changes.

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

Navigate to the line situated at the exact midpoint vertically

I have a div with child elements, each containing a line of text. <div id="aboutxt"> <div class="line">TEXT_LINE_ONE</div> <div class="line">TEXT_LINE_TWO</div> <div class="line">TEXT_LINE_THREE</div> ...

What is the best method to access an element with Vue.js?

I currently have a form set up like this <form v-on:submit.prevent="save_data(this)"></form> and a method defined in Vue.js like this methods: { save_data: function(f){ } } In jQuery, we can access the form using $(f)[0] My question ...

Compilation of CSS by Webpack resulting in peculiar class identifiers

Currently, I am using webpack for developing a React app with a NodeJS backend. I've encountered an issue with styling the app as webpack seems to be interfering with my CSS, causing changes in class names. For example, in my base.css file, I have d ...

Is it possible to change XML using Ajax technology?

Is it possible to update a value in an XML file using JavaScript/Ajax? I've managed to access the XML file with Ajax and utilize its values in my script. Now, I want to send any updates made by the script back to the XML file on the server using Ajax ...

What's the best way to adjust the card column for mobile view resizing?

I am trying to modify the card view for mobile devices to display as a 2-column layout. I have adjusted the flex length and grid size in my code, but I still can't achieve the desired result. Can someone guide me on how to make this change? Current d ...

Using the map function with a React onClick handler

After tirelessly scouring the internet for answers to my query, I've hit a dead end. My goal is to implement a basic react click handler on my button, but for some reason, it just won't cooperate. It's likely something incredibly straightfor ...

Creating an 8-bit grayscale JPEG image using HTML5 and encoding it from a canvas source

Is there a simple method to convert an 8-bit grayscale JPEG from Canvas using client side technologies in a web browser (such as HTML5, canvas, WebGL, and JavaScript)? Are there any pre-made JavaScript libraries available for use, without requiring extens ...

Adjusting label color when input is deactivated in a React application using TypeScript

Is there a way to change the label color in my view when the input is disabled using Typescript or CSS? This is the interface I am working with: interface image Here is the code snippet: <tr> <td className="name">Critère d&a ...

Changing the Displayed Content with a Simple Click of a Link

Layout Overview In the process of developing a tool to streamline work tasks, I want to ensure that I am following best practices. My goal is for the website to initially display only column A, with subsequent columns generated upon clicking links in the ...

Having trouble identifying the CSS style being applied to a specific element

In this image, a red border is seen on the input fields indicating an error with some CSS style being applied. Despite this, it is difficult to determine which CSS selector is causing this as Firebug does not reveal any applied styles. https://i.stack.img ...

It seems that FireFox does not fully support IFrame Data URIs

Whenever I attempt to load a PDF Data URI into an iframe (for example, src="data:application/pdf;base64,...") in FireFox (version 18.0.2 [latest release], on OSX), it ends up triggering a download window instead. Just take a look at the website JSPDF.com ...

Can we show the dropdown with the active button?

Can someone assist me in transforming my sidebar buttons into dropdowns when viewed on a responsive layout? I'm looking for something similar to the sidebar (on the left) featured on this website: If possible, I would like the dropdown to only displa ...

Oops! The regular expression flag "ajax" in Javascript is not valid and is causing

This is my function: public ActionResult RetrieveData(int id) { string name = "Jane"; return Json( new {result=name}); } I'm attempting to fetch information from this function using the code below, but I keep getting errors. Could y ...

What is the simplest method for comparing transaction amounts?

I'm in the process of integrating PayPal into my website using their REST API. My goal is to allow users to input the amount they want to deposit. While I can obtain the total during payment creation, I'm unsure how to smoothly pass it to the exe ...

The usage of arrow functions in ReactJS programming

I'm working on a React component that has the following structure: import React, { PropTypes, Component } from 'react'; import { Accordion, Panel, PanelGroup, Table } from 'react-bootstrap'; const FormCell = ({ data }) => ( ...

The specified CSS background image is not correctly aligned with the dimensions of the selector

I have multiple non-local images that I want to use as background images for classes with a width of 500px and height of 330px. Even though these dimensions are specified in the CSS properties for the class, the background: url('http://www.example.com ...

My website's logo is not appearing on the navigation bar in the HTML code

Hi there! I recently tried adding a logo to my navigation bar in an HTML file, but for some reason, the logo doesn't appear when I run the file. I'm currently learning web development through a course on Coursera, and I am quite new to programmin ...

Struggling to retrieve a response from the ListUsers endpoint in OKTA using the okta-sdk-nodejs Client's listUsers function

Code snippet: async fetchUsersByEmail(email) { try { return await Promise.all([ oktaClient.listUsers({ search: email, }), ]).then((response) => { console.log(response); }); } catch (error) { ...

Mastering the Art of Displaying Links in Columns within a Table Using ReactJS

I have the following code that fetches data from the backend and displays it in a table. Everything is working correctly. Now, I need to make the first column in the table appear as a link. How can I achieve that? const EditController = () => { c ...

Implementing a Javascript solution to eliminate the # from a URL for seamless operation without #

I am currently using the pagepiling jQuery plugin for sliding pages with anchors and it is functioning perfectly. However, I would like to have it run without displaying the '#' in the URL when clicking on a link like this: www.mysite.com/#aboutm ...