0

I'd like to have multiple <div> on a page, each with a <button> that toggles the <div>'s visibility.

If found toggle show/hide div with button?, and modeled my attempt on it--this is for one <div> toggled by one <button> on the page.

You can see my attempt at https://jsfiddle.net/pjamesnorris25/8xhtfb1p/17/.

I thought wrapping the collection_button[count].onclick = function() in a for loop over all of the <button>s would do the trick, but clicking each of the <button>s results only in the last <div> being toggled as the console.log shows--no matter which <button> is clicked the console shows that "p88c3-button is trying to toggle p88c3-div" .

So to be clear, how can one write the code, using plain javascript, so that each time one clicks on the "reply - p88c1" button, it toggles the visibility of "div - p88c1" and when one clicks on the "reply - p88c2" button, it toggles the visibility of "div - p88c2" and so on?

The two non-jQuery solutions at How do I associate individual buttons with individual divs? do what I want, but they both rely on a DOM relationship between the <button> and the <div>, i.e., parentNode and nextElementSibling, that doesn't obtain in my case, and I don't see how to modify either to work for me.

Thanks in advance for whatever help you can give me.

P. James Norris
  • 158
  • 2
  • 14
  • your code should be self-contained in the question, not on an external site. However I did look and confirmed my first suspicion - this is a duplicate of the very common question that I'm about to link as a duplicate. In short, you need to declare your loop variable `count` with `let` in the loop header (you don't actually declare it at all, which is bad, but you'd see the same bug if you used `var`) – Robin Zigmond Jun 29 '23 at 20:52
  • Does this answer your question? [JavaScript closure inside loops – simple practical example](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Robin Zigmond Jun 29 '23 at 20:53

1 Answers1

1

Instead of unneeded loops, I like to delegate my click handlers to the body. Then inside of it, detect the class of the element clicked to see if matches the class of my buttons.

Instead of ids on the button, I changed that to data-target="#". Where that will be the ID of the div you want toggled.

By default using CSS, I set all of the reply-divs to display none to hide them.

Then in the click handler I simply toggle a class called active that sets the display to block for the target div.

document.body.addEventListener("click",(e) => {
  const el = e.target;
  if(el.classList.contains("button-reply")){
    const target = document.querySelector(el.dataset.target);
    target.classList.toggle("active")
  }
});
.reply-div {
  display: none;
}

.reply-div.active {
  display: block;
}
<table border="1" style="margin-bottom:5px; margin-left:26px; border:black thin solid;" id="p88c1">
  <tr>
    <td align="right"><button class="button-reply" data-target="#p88c1-div">reply - p88c1</button></td>
  </tr>
</table>
<!-- comment -->
<div class="reply-div" id="p88c1-div">p88c1 - div</div>
<table border="1" style="margin-bottom:5px; margin-left:26px; border:black thin solid;" id="p88c2">
  <tr>
    <td align="right"><button class="button-reply" data-target="#p88c2-div">reply - p88c2</button></td>
  </tr>
</table>
<!-- comment -->
<div class="reply-div" id="p88c2-div">p88c2 - div</div>
<table border="1" style="margin-bottom:5px; margin-left:26px; border:black thin solid;" id="p88c3">
  <tr>
    <td align="right"><button class="button-reply" data-target="#p88c3-div">reply - p88c3</button></td>
  </tr>
</table>
<!-- comment -->
<div class="reply-div" id="p88c3-div">p88c3 - div</div>
imvain2
  • 15,480
  • 1
  • 16
  • 21