skip to Main Content

Hello I am a relative rookie when it comes to web design in general and am having a heck of a time trying to figure out how to toggle a png image from hidden to visible. Effectively what I want to happen is to have a base image that is always displayed on the webpage and be able to use checkboxes to toggle on or off specific png images. I am sure that it is a very simple thing to do but after spending a half a day searching Google I thought better of myself and decided to ask for some help.

Here is the HTML, CSS, and JavaScript that I have:

<!DOCTYPE html>
<html>
    <head>
        <!---->
        <style>
        .buttonBar {
            width:64%;
            margin: 2% 17%;
            padding: 1%;
            border: 2px solid #44506e;
            border-radius: 5px;
            background-color: #c1baa9;
        }
        .pngCake {
            position: relative;
            width:60%;
            margin-left: 17%;
            padding: 3%;
            border: 2px solid #44506e;
            border-radius: 5px;
            background-color: #c1baa9;
        }
        #base {
            position: relative;
            top: 0;
            left: 0;
        }
        .pngCake #png, .pngCake #png1 {
            position: absolute;
            top: 0;
            left: 0;
            visibility: hidden;
        }
    </style>
        <title>Image Cake</title>
    </head>
    <body>
        <div class="buttonBar">
            <label class="cb">
                <input type="checkbox" onclick="pngLayer()">
                <span class="cm"></span>
            PNG</label>
            <!-- Printer Checkbox -->
            <label class="cb">
                <input type="checkbox" onclick="pngLayer1()">
                <span class="cm"></span>
            PNG 1</label>
        </div>
        <div class="pngCake">
            <img id="base" src="base.png"></img>
            <img id="png" src="png.png"></img>
            <img id="png1" src="png1.png">
        </div>
        <script>
            function pngLayer() {
                var portCheck = document.getElementById("png");
                portCheck.style.visibility = "visible";
            }
            function pngLayer1() {
                var portCheck = document.getElementById("png1");
                portCheck.style.visibility = "visible";
            }
        </script>
    </body>
</html>

In JavaScript I have tried using a toggle command to pull a duplicate of the CSS with the visibility set to visible.
In addition I have tried using if else statements to check and see if the visibility of the png is set to hidden vs visible and changing it.
In each case the result did not work.

if(document.getelementbyid("png").style.visibility == "hidden") {
    document.getelementbyid("png").style.visibility == "visible"
}
else {
    document.getelementbyid("png").style.visibility == "hidden
}
if (document.getelementbyid("png").style.visibility == "hidden") {
  document.getelementbyid("png").style.visibility == "visible"
} else {
  document.getelementbyid("png").style.visibility == "hidden"
}

function pngLayer() {
  var portCheck = document.getElementById("png");
  portCheck.style.visibility = "visible";
}

function pngLayer1() {
  var portCheck = document.getElementById("png1");
  portCheck.style.visibility = "visible";
}
.buttonBar {
  width: 64%;
  margin: 2% 17%;
  padding: 1%;
  border: 2px solid #44506e;
  border-radius: 5px;
  background-color: #c1baa9;
}

.pngCake {
  position: relative;
  width: 60%;
  margin-left: 17%;
  padding: 3%;
  border: 2px solid #44506e;
  border-radius: 5px;
  background-color: #c1baa9;
}

#base {
  position: relative;
  top: 0;
  left: 0;
}

.pngCake #png,
.pngCake #png1 {
  position: absolute;
  top: 0;
  left: 0;
  visibility: hidden;
}
<div class="buttonBar">
  <label class="cb">
                <input type="checkbox" onclick="pngLayer()">
                <span class="cm"></span>
            PNG</label>
  <!-- Printer Checkbox -->
  <label class="cb">
                <input type="checkbox" onclick="pngLayer1()">
                <span class="cm"></span>
            PNG 1</label>
</div>
<div class="pngCake">
  <img id="base" src="base.png"></img>
  <img id="png" src="png.png"></img>
  <img id="png1" src="png1.png">
</div>

3

Answers


  1. See these, the comments in the code explain how it works.
    (I have only copied what I have changed)

    <div class="buttonBar">
      <label class="cb">
        <input type="checkbox" data-id='png' onclick="pngLayer(event)">
                              <!-- Here is the data attribute, and 
                                    remember to pass the event handler 
                                  into the function -->
        <span class="cm"></span>
        PNG</label>
      <!-- Printer Checkbox -->
      <label class="cb">
        <input type="checkbox" data-id='png1' onclick="pngLayer1(event)">
                              <!-- Same thing here -->
        <span class="cm"></span>
        PNG 1</label>
    </div>
    
    function pngLayer(event) {
      document.getElementById("png").style.visibility = event.target.checked ? "visible" : 'hidden';
      // You can skip creating a variable and directly access the HTML node methods
      // You access the event handler from the checkbox that triggered the function 
      // you get whether or not the checkbox is ticked - event.target.checked does this.
      // Then you use the ternary - target.target.checked ? 'value if true' : 'value if false'
    }
    function pngLayer1(event) {
      document.getElementById("png1").style.visibility = event.target.checked ? "visible" : 'hidden';
    }
    
    // For extra points these functions can be combined into one function
    function pngLayerCombined(event) {
      document.getElementById(event.target.dataset.id).style.visibility = event.target.checked ? "visible" : 'hidden';
      // Add a dataset attribute to each checkbox to store the id of the png they correspond to 
      // Use event.target.dataset.id to access this value and feed it into document.getElementById()
    }
    

    event.target.checked – returns either true (checked) or false (unchecked) depending on the state of the checkbox.
    Ternary Operator Docs

    Hope this helps.

    Login or Signup to reply.
  2. I had a look at your script but it’s an absolute mess so it would take far less time creating such a simple program from scratch.

    You only need one image tag and to just change the src attribute as the user clicks on the selection control.

    The image selection control is best represented by radio buttons that only allow one choice at a time as there’s no reason in having three images stacked up on each other.

    Ok, here’s the script… replace the image paths where I have indicated in the comments and keep practicing.

    <!DOCTYPE html>
       <head>    
          <style type="text/css"> 
             .cont {
                position:absolute; 
                wdith:max-content; 
                height:max-content; 
                padding:10px; 
                border:1px solid black;
             }
          </style>
       </head>
        
       <body onload="I.src=Path+'City.jpg';">
          <script type="text/javascript">
             var Path='C:/Users/User/Pictures/';  // <-- Change the path here to wherever your images are kept
          </script>
        
          Select image:
        
          <!-- Change the three image file names below to what you have -->
        
          <input type="radio" name="N" onclick="I.src=Path+this.value;" value="Sunshine.jpg" checked> 
        
          <input type="radio" name="N" onclick="I.src=Path+this.value;" value="flowers.jpg">
        
          <input type="radio" name="N" onclick="I.src=Path+this.value;" value="City.jpg">
        
          <br><br>
        
          <div class="cont">Image output:<br>
        
             <img id="I" src="" height="300" width="300" border="1">
        
          </div>
        
       </body>
    </html>
    
    Login or Signup to reply.
  3. CodePen

    In this CodePen it’s what I think could be a good way of solving this, please give a good read before trying it out to see if it matches your use case.

    The HTML part is pretty much whatever you need to be, I just placed a wrapper, so I could style them better for the test.

    In JS part,
    There’s an array of strings, where I map though them to build my imgs

    const images = ["1", "2", "3", "4"];
    

    This is where you could place your URL’s.

    Right under it, I map the images and create img and checkbox (if you need to create the checkbox elsewhere, you can just create a different function to append it differently than the one I have)

    And then there’s the onToggle function, where I get the img by its id, (that I set when I was creating it) and then check if the class hidden is on the class list, if it’s not, I add it, otherwise I remove it, toggling the image visibility.

    // JS
    const onToggle = (id) => {
      const image = document.querySelector(`#wrapper img#${id}`);
    
      if (image.classList.contains("hidden")) {
        image.classList.remove("hidden");
      } else {
        image.classList.add("hidden");
      }
    };
    

    And the CSS

    // CSS
    img.hidden{
        display: none;
    }
    

    I did it this way, but honestly you could use inline styles if you prefer to.

    if (x.style.display === "none") {
        x.style.display = "block";
    } else {
        x.style.display = "none";
    }
    

    Thinking as developer, since you are loading multiple images, I would try to minimize adding them manually to just looping though them.
    But you could do this manually too, invoking the function onToggle and passing the id in each checkbox onclick. Like so:

    <div class="buttonBar">
      <label class="cb">
                    <input type="checkbox" onclick="onToggle('png')">
                    <span class="cm"></span>
                PNG</label>
      <!-- Printer Checkbox -->
      <label class="cb">
                    <input type="checkbox" onclick="onToggle('png1')">
                    <span class="cm"></span>
                PNG 1</label>
    </div>
    <div class="pngCake">
      <img id="base" src="base.png"></img>
      <img id="png" src="png.png"></img>
      <img id="png1" src="png1.png">
    </div>
    
    const wrapper = document.querySelector("#wrapper");
    
    const images = ["1", "2", "3", "4"];
    
    images.map((potentialURL, id) => {
      const imgId = `img-${id}`
      const img = document.createElement("img");
      // Instead of using picsum, use potentialURL where it should be   your URL's
      img.setAttribute("src", "https://picsum.photos/200/300");
      img.setAttribute("id", imgId);
      const checkbox = createCheckBox(imgId);
      wrapper.appendChild(checkbox);
      wrapper.appendChild(img);
    });
    
    const onToggle = (id) => {
      const image = document.querySelector(`#wrapper img#${id}`);
    
      if (image.classList.contains("hidden")) {
        image.classList.remove("hidden");
      } else {
        image.classList.add("hidden");
      }
    };
    
    function createCheckBox(id) {
      const checkbox = document.createElement("input");
      checkbox.setAttribute("type", "checkbox");
      checkbox.onclick = () => onToggle(id);
      return checkbox;
    }
    body {
      background: black;
    }
    
    #wrapper{
      display: flex;
      gap: 1rem;
    }
    
    img {
      height: 200px;
      width: 200px;
    }
    
    img.hidden{
      display: none;
    }
    <div id='wrapper'></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search