Home > Enterprise >  Toggle re-hides all divs; need parent div to remain visible
Toggle re-hides all divs; need parent div to remain visible

Time:01-27

Apologies in advance, I'm not terribly familiar with Javascript, but I do understand what this code is doing and why it is causing me this problem. I'm just not sure how to go about solving it AT all.

On my webpage I have an open/close dialogue toggle which is the parent div, the dialogue box is hidden upon the page loading. Within this dialogue box are more hidden divs for the dialogue options. Problem is, when one of the dialogue options is clicked, the script hides the entire dialogue box, preventing any of the dialogue options from being seen, because it can only show one div at a time, regardless of its parent or child status. When a div is clicked, all other divs are re-hidden. I need the parent div to remain visible until the dialogue box toggle is clicked again. The individual choices DO need to hide/unhide when another choice is clicked.

Not sure if I should include any CSS here, it's just styling the dialogue box and its buttons within.

<div id="dialogue" style="display:none;">
    <div >
        Room description here. What do you do?

        <div >
            <a href="#" onclick="divVisibility('cat');">Pet the cat.</a>
            <br>

            <div id="cat" style="display:none;">aw yeah kitty time</div>

            <a href="#" onclick="divVisibility('radio');">Turn on the radio.</a>
            <br>

            <div id="radio" style="display:none;">
                <br>
                audio file and tracklist here
            </div>
        </div>
    </div>
</div>

<span >
    <a href="#" onclick="divVisibility('dialogue');">[Open/close dialogue.]</a>
</span>

<script type="text/javascript">
    var divs = ["cat", "radio", "dialogue"];
    var visibleDivId = null;

    function divVisibility(divId) {
        if(visibleDivId === divId) {
            visibleDivId = null;
        } else {
            visibleDivId = divId;
        }

        hideNonVisibleDivs();
    }

    function hideNonVisibleDivs() {
        var i, divId, div;

        for(i = 0; i < divs.length; i  ) {
            divId = divs[i];
            div = document.getElementById(divId);

            if(visibleDivId === divId) {
                div.style.display = "block";
            } else {
                div.style.display = "none";
            }
        }
    }
</script>

I probably need a third function here because currently all the toggles are grouped together, hence why they're interacting like this, but I don't have the first clue how to accomplish this. I have been looking and haven't found anything that seems to match my needs.

CodePudding user response:

Made a few corrections to your HTML so the href does not refresh the page on click. Also added in a few attributes (aria-controls) to track which div the button controls. I added comments to the JavaScript. There are plenty of Aria attributes they typically help with accessibility but they are super useful for keeping track of things in HTML and passing information to JavaScript.

//create a function to handle the click that takes in the event as a argument
function handleClick(event) {
  //find out which div the button controls
  const ariaControls = event.currentTarget.getAttribute("aria-controls"),
    //select the controlled div
    controlledAria = document.getElementById(ariaControls);
  // if the controlled div is cat
  if (ariaControls === "cat") {
    // hide the radio div
    document.getElementById("radio").classList.add("hide");
    // if the controlled div is radio
  } else if (ariaControls === "radio") {
    // hide the car div
    document.getElementById("cat").classList.add("hide");
  }
  //toggle the hide div on the controlled div
  controlledAria.classList.toggle("hide");
}
//select all the buttons
const buttons = document.querySelectorAll("button");
//for each button add an event listener when the button is clicked run the handle click function
buttons.forEach(button => button.addEventListener("click", handleClick))
.hide {
  display: none;
}
<div id="dialogue" >
  <div >
    Room description here. What do you do?

    <div >
      <button aria-controls="cat">Pet the cat.</button><br>
      <div id="cat" >aw yeah kitty time</div>
      <button aria-controls="radio">Turn on the radio.</button><br>
      <div id="radio" >audio file and tracklist here
      </div>
    </div>
  </div>
</div>
<span ><button aria-controls="dialogue">[Open/close dialogue.]</button></span>

  •  Tags:  
  • Related