Search code examples
javascriptclasstoggleshow-hide

Show class div and hide previous - pure javascript


I was actually using a script which allowed me to Show a div onclick and hide others but now I need to do the same with "class" instead of "id".

My current script:

function layout(divName){
var hiddenVal = document.getElementById("tempDivName");
if(hiddenVal.Value != undefined){
    var oldDiv = document.getElementById(hiddenVal.Value); 
    oldDiv.style.display = 'none'; 
}

var tempDiv = document.getElementById(divName); 
tempDiv.style.display = 'block';              

hiddenVal.Value = document.getElementById(divName).getAttribute("class");}

What I tried using getElementsByClassName :

function layoutNEW(divName){
var hiddenVal = document.getElementById("tempDivName");
if(hiddenVal.Value != undefined){
    var oldDiv = document.getElementById(hiddenVal.Value); 
    oldDiv.style.display = 'none'; 
}
var tempDiv = document.getElementsByClassName(divName);
for ( var i=0, len=tempDiv.length; i<len; ++i ){
    tempDiv[i].style.display = 'block';  
}
hiddenVal.Value = document.getElementById(divName).getAttribute("id");}

Any ideas ?

EDIT : A working example of my current script with "id" : JSFiddle

EDIT 2: It works great, but when the div (class) is cloned, only one of them is showing the div. Do you have an idea about this ? Where is a JSFiddle demonstrating the situation: JSFiddle


Solution

  • I think this is what you'd need. The idea is that you can use a data property on your <a> tags that will tell your click handler which classname to look for when showing an element. From there, you just hide the others. Here's a working demo:

    var toggleControls = document.querySelectorAll("[data-trigger]");
    var contentDivs = document.querySelectorAll(".toggle");
    for (var i = 0; i < toggleControls.length; i++) {
      toggleControls[i].addEventListener("click", function(event) {
        var trigger = event.target;
        var selector = "." + trigger.getAttribute("data-trigger");
        var divToShow = document.querySelector(selector);
        for (j = 0; j < contentDivs.length; j++) {
          contentDivs[j].style.display = "none";
        }
        divToShow.style.display = "block";
      });
    }
    .toggle {
      height: 100px;
      width: 100px;
      display: none;
    }
    .div1 {
      background-color: red;
    }
    .div2 {
      background-color: blue;
    }
    .div3 {
      background-color: purple;
    }
    .div4 {
      background-color: green;
    }
    <a href="#" data-trigger="div1">Show Div1</a>
    <br/>
    <a href="#" data-trigger="div2">Show Div2</a>
    <br/>
    <a href="#" data-trigger="div3">Show Div3</a>
    <br/>
    <a href="#" data-trigger="div4">Show Div4</a>
    <div class="toggle-container">
      <div class="toggle div1"></div>
      <div class="toggle div2"></div>
      <div class="toggle div3"></div>
      <div class="toggle div4"></div>
    </div>

    EDIT - As per updated question

    In order to get this to work with dynamically created elements, you will have to put the var contentDivs = ... inside of the click handler, so you get a live version of that array. Also, you will need to change .querySelector to .querySelectorAll as the former only grabs the first matching element, not all as the latter does.

    Here's what the code would look like: (note - I also moved the click handler into an outside function so it was not being recreated for every iteration of the loop, as is good practice)

    function clickHandler(event) {
        var contentDivs = document.getElementsByClassName("toggle"); // get live set of contentDivs in case any were added dynamically
        var trigger = event.target;
        var selector = "." + trigger.getAttribute("data-trigger");
        var divsToShow = document.querySelectorAll(selector); // grab all matching divs
        for (var i = 0; i < contentDivs.length; i++) {
            contentDivs[i].style.display = "none";
        }
        for (var j = 0; j < divsToShow.length; j++) {
            divsToShow[j].style.display = "block";
        }
    }
    var toggleControls = document.querySelectorAll("[data-trigger]");
    for (var i = 0; i < toggleControls.length; i++) {
      toggleControls[i].addEventListener("click", clickHandler);
    }
    
    
    function cloneDiv() {                
      var elmnt = document.getElementsByClassName("container");
    
      for ( var i=0; i<elmnt.length; i++ ) {
        var cln = elmnt[i].cloneNode(true);
      }
      document.body.appendChild(cln);
      document.getElementById("clone").appendChild(cln);
    }
    window.onload = cloneDiv();