1

I am trying to display a green, yellow, or red dot image depending on what color the user selects. I based my code on something I found on this question.

For some reason, the function is not working. Currently nothing happens when the user makes a selection.

var statusCode = document.getElementById('statusCode');
var greenDot = document.getElementById('greenDot');
var yellowDot = document.getElementById('yellowDot');
var redDot = document.getElementById('redDot');

function myfunction() {
  if (statusCode.value == 'Green') {
    greenDot.style.display = 'circle';
    yellowDot.style.display = 'none';
    redDot.style.display = 'none';
  } 
  else if (statusCode.value == 'Yellow') {
    greenDot.style.display = 'none';
    yellowDot.style.display = 'circle';
    redDot.style.display = 'none';
  } 
  else if (statusCode.value == 'Red') {
    greenDot.style.display = 'none';
    yellowDot.style.display = 'none';
    redDot.style.display = 'circle';
  }
}
<select id="statusCode" onload="myFunction()">
  <option value="Green">Green</option>
  <option value="Yellow">Yellow</option>
  <option value="Red">Red</option>
</select>

<p>
  <img src="http://clipart-library.com/image_gallery/156788.png" style="display: none;" id="greenDot">
  <img src="http://www.clker.com/cliparts/o/b/y/x/Z/c/yellow-dot-md.png" style="display: none;" id="yellowDot">
  <img src="http://www.clker.com/cliparts/s/o/v/c/T/Y/red-dot-md.png" style="display:none;" id="redDot">
</p>
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
BeeTee
  • 21
  • 4
  • 1
    There is no such thing as `display = 'circle';` You have [a limited number of choices for what to set `display` to](https://developer.mozilla.org/en-US/docs/Web/CSS/display). You likely want "inline-block" or "block"; – Heretic Monkey Feb 13 '19 at 19:07
  • Possible duplicate of [Show and hide html element on selected option change](https://stackoverflow.com/questions/27921922/show-and-hide-html-element-on-selected-option-change) – Jack Moody Feb 13 '19 at 19:22

4 Answers4

1

I fix a little your code:

  • change way of read select value (in line let value =....)
  • change html <select ... onload... to oninput
  • change js myfunction to myFunction (F uppercase)
  • change in js style.display = 'circle' to 'block'
  • call myFunction() in script bottom to init first picture
  • change <img src=http://... to https:// (but may be this was needed only here in SO)

var statusCode = document.getElementById('statusCode');
var greenDot = document.getElementById('greenDot');
var yellowDot = document.getElementById('yellowDot');
var redDot = document.getElementById('redDot');

function myFunction() {

    const value = statusCode.options[statusCode.selectedIndex].value

    if(value == "Green") {        
        greenDot.style.display = 'block';
        yellowDot.style.display = 'none';
        redDot.style.display = 'none';
    }
    else if(value == "Yellow"){
        greenDot.style.display = 'none';
        yellowDot.style.display = 'block';
        redDot.style.display = 'none';
    }
    else if(value == "Red"){
        greenDot.style.display = 'none';
        yellowDot.style.display = 'none';
        redDot.style.display = 'block';
    }
}

myFunction();
<select id="statusCode" onchange="myFunction()"> 
  <option value="Green">Green</option>
  <option value="Yellow">Yellow</option>
  <option value="Red">Red</option>
</select>

<p>    
  <img src="https://clipart-library.com/image_gallery/156788.png" style="display: none;" id="greenDot"/>
  <img src="https://www.clker.com/cliparts/o/b/y/x/Z/c/yellow-dot-md.png" style="display: none;" id="yellowDot"/>
  <img src="https://www.clker.com/cliparts/s/o/v/c/T/Y/red-dot-md.png" style="display:none;" id="redDot"/>
</p>
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
  • Well, `statusCode.value` is still shorter and easier to remember. – Roko C. Buljan Feb 13 '19 at 20:06
  • Also, I think you want to use `onchange` for a ` – Roko C. Buljan Feb 13 '19 at 20:08
  • @RokoC.Buljan you have right. If this was my code, I will write it completely different - however the OP is probably beginner so i focus only on fix bugs int code to make it works (with minimal changes to original code) - not to refactor it. – Kamil Kiełczewski Feb 13 '19 at 20:15
  • I was always glad, in my early days, when someone helped me refactor my code - to speed up my learning curve and not repeat some basic mistakes ;) – Roko C. Buljan Feb 13 '19 at 20:51
0

There are a few mistakes with the code

  1. The event handler for the dropdown is onchange
  2. The myfunction is case sensitive
  3. Set the visible dot to display block or some other value (https://developer.mozilla.org/en-US/docs/Web/CSS/display)
YarGnawh
  • 4,574
  • 6
  • 26
  • 37
  • 1
    I tried onchange as well and in my actual code myFunction has correct capitalization not sure what happened here. I didn't think that 'circle' would display but I tested it and it worked so I just went with it. Thank you for your help. – BeeTee Feb 13 '19 at 19:37
  • By such answers people might think w3schools is an authoritative resource worth learning from. They've done and still do so much harm to the programming community by providing low quality and inadequate documentation. They even sell worthless and fake diplomas. – Roko C. Buljan Feb 13 '19 at 19:47
0

Here’s a method of creating this status dot without any images at all, using a bit of CSS:

// Get references to the relevant elements
const statusCode = document.getElementById('statusCode');
const dot = document.getElementById('dot');

// Register an event handler for the select menu’s change event
statusCode.addEventListener('change', e => {
  // Remove all existing color classes
  dot.classList.remove('dot-red', 'dot-yellow', 'dot-green');

  // Apply the correct color class using the value of the select menu
  dot.classList.add(`dot-${e.target.value}`);
});

// Manually trigger the event once to set the initial color
statusCode.dispatchEvent(new Event('change'));
.dot {
  /* Setup dimension */
  width: 10px;
  height: 10px;

  /* Make the dot round (side length / 2) */
  border-radius: 5px;

  /* Set a default color */
  background-color: black;

  /* Position the dot next to the menu */
  display: inline-block;

  /* Apply a light shadow to make low contrast colors more visible */
  box-shadow: 0 0 5px gray;
}

.dot-red {
  background-color: red;
}

.dot-yellow {
  background-color: yellow;
}

.dot-green {
  background-color: lime;
}
<select id="statusCode">
  <option value="green">Green</option>
  <option value="yellow">Yellow</option>
  <option value="red">Red</option>
</select>

<div id="dot" class="dot"></div>
MTCoster
  • 5,868
  • 3
  • 28
  • 49
  • 2
    Thank you for your solution! I went with another because I was more familiar with it. I did upvote you but I don't have a good enough reputation for it show. – BeeTee Feb 13 '19 at 19:41
0

Imagine one day, your colleague asks you to add 50 (or N) status codes.
Copy-paste the if statements, each 52 lines long, 50 times and manually naming the elements that should become hidden is not the right way to approach the problem and programming in general.
There are many ways, I'll show you one:

  • Don't use HTML-inline javascript, use Element.addEventListener() instead - Look forward to keep your JS in one place, not separated in different places (HTML and JS files)
  • Assign to your images a data-id attribute that have the same value as the Option elements value.
  • Use Element.classList and it's methods to remove() or add() a class (see CSS)

the following will now work for an indefinite number of elements:

const status = document.querySelector('#statusCode');
const parent = document.querySelector('#images');
const allImg = parent.querySelectorAll('[data-id]'); // get them all!

function showImage() {
  allImg.forEach(el => el.classList.remove('is-visible'));       // Hide all images
  const img = parent.querySelector(`[data-id="${this.value}"]`); // Find image by data-id
  if (img) {
    img.classList.add('is-visible'); // Show it (if found)
  }
}

statusCode.addEventListener('change', showImage);
#images [data-id] {
  display: none;
}

#images [data-id].is-visible {
  display: block;
}
<select id="statusCode">
  <option disabled selected>-Select status color-</option>
  <!-- values should reflect exactly the images data-id value -->
  <option value="green">Green</option>
  <option value="yellow">Yellow</option>
  <option value="red">Red</option>
</select>

<div id="images">
  <img data-id="green"  src="//placehold.it/50x50/0f0">
  <img data-id="yellow" src="//placehold.it/50x50/ff0">
  <img data-id="red"    src="//placehold.it/50x50/f00">
</div>

and even the above code can be further improved for even (yet just slightly) better performance.


Resources:

https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach
https://developer.mozilla.org/en/docs/Web/API/Element/classList

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313