0

I am trying to be able to select a parent div and have it select its respective child radio button.

Inside this parent div there is a show/hide link that shows some info in a div that's also inside this container.

Problem is when I click the show/hide link of a parent div that isn't clicked, I want it to show/hide that hidden div without selecting that div's radio button/parent div.

Looking for a clean vanilla javascript solution.

In my code so far, it's not properly selecting the parent div of radio button, and then I want to make sure the show/hide link doesn't select the div if it wasn't already selected.

HTML

<div class="box" onclick="check(this)">
  <h3>This is div 1</h3>
  <input id="radio1" name="field" type="radio" />
  <div>
  <div class="hiddenstuff">
    You see me now
  </div>
  <p><a href="#" class="link" onclick="showhide(this)">show</a></p>
  </div>

</div>
<br />
<div class="box" onclick="check(this)">
  <h3>This is div 2</h3>
  <input id="radio2" name="field" type="radio" />
  <div>
  <div class="hiddenstuff">
    You see me now
  </div>
  <p><a href="#" class="link" onclick="showhide(this)">show</a></p>
  </div>

</div>

CSS:

.box {
  width: 300px;
  height: 150px;
  padding: 10px;
  background-color: yellow;
  cursor: pointer;
}
.checked {
  border: 3px solid blue;
}

.hiddenstuff {
  color: red;
  padding: 10px;
  display: none;
}

JS:

function check(box) {
  var radioId = this.querySelectorAll('input[type="radio"]').value;
    document.getElementById(radioId).click();
  document.querySelectorAll(".box").forEach(function (item) {
    item.classList.remove("checked");
  });
  if ((input[0].checked = true)) {
    box.classList.add("checked");
  }
  return false;
}

function showhide(elem) {
  var cont = elem.parentNode.previousElementSibling;
  if (cont.style.display != "block") {
    cont.style.display = "block";
    elem.innerHTML = "hide";
  } else {
    cont.style.display = "none";
    elem.innerHTML = "show";
  }
  return false;
  elem.stopPropagation();
}
.box {
  width: 300px;
  height: 150px;
  padding: 10px;
  background-color: yellow;
  cursor: pointer;
}
.checked {
  border: 3px solid blue;
}

.hiddenstuff {
  color: red;
  padding: 10px;
  display: none;
}
<div class="box" onclick="check(this)">
  <h3>This is div 1</h3>
  <input id="radio1" name="field" type="radio" />
  <div>
  <div class="hiddenstuff">
    You see me now
  </div>
  <p><a href="#" class="link" onclick="showhide(this)">show</a></p>
  </div>

</div>
<br />
<div class="box" onclick="check(this)">
  <h3>This is div 2</h3>
  <input id="radio2" name="field" type="radio" />
  <div>
  <div class="hiddenstuff">
    You see me now
  </div>
  <p><a href="#" class="link" onclick="showhide(this)">show</a></p>
  </div>

</div>
Mia Sno
  • 947
  • 1
  • 6
  • 13
  • I have to say I don't understand your "Problem.." part, wonted behavior. – ikiK Jul 13 '20 at 22:32
  • When I click "show" link, I want it to show/hide the hiddenstuff div, but not click on the parent div/radio button – Mia Sno Jul 13 '20 at 22:46

1 Answers1

1

Is this what you need?

If so, add event.stopPropagation(); at start of your clicking link function.

Also i believe your id fetching was wrong so i changed it:

querySelectorAll returns nod list, not element. Then you need to loop in it and fetch .id not .value to get the id.

var el = box.querySelectorAll('input[type="radio"]');
      var radioId = "";
      el.forEach(element => {
        radioId = element.id
      });

Use box, not this. Also input[0] was undefined, in my solution you have el, use that in your if condition.

function check(box) {
  var el = box.querySelectorAll('input[type="radio"]');
  var radioId = "";
  el.forEach(element => {
    radioId = element.id
  });

  //console.log(radioId);
  document.getElementById(radioId).click();
  document.querySelectorAll(".box").forEach(function(item) {
    item.classList.remove("checked");
  });
  if ((el[0].checked = true)) {
    box.classList.add("checked");
  }
  return false;
}

function showhide(elem) {
event.stopPropagation();
  var cont = elem.parentNode.previousElementSibling;

  if (cont.style.display != "block") {
    cont.style.display = "block";
    elem.innerHTML = "hide";
  } else {
    cont.style.display = "none";
    elem.innerHTML = "show";
  }
  return false;
  
}
.box {
  width: 300px;
  height: 150px;
  padding: 10px;
  background-color: yellow;
  cursor: pointer;
}

.checked {
  border: 3px solid blue;
}

.hiddenstuff {
  color: red;
  padding: 10px;
  display: none;
}
<div class="box" onclick="check(this)">
  <h3>This is div 1</h3>
  <input id="radio1" name="field" type="radio" />
  <div>
    <div class="hiddenstuff">
      You see me now
    </div>
    <p><a href="#" class="link" onclick="showhide(this)">show</a></p>
  </div>

</div>
<br />
<div class="box" onclick="check(this)">
  <h3>This is div 2</h3>
  <input id="radio2" name="field" type="radio" />
  <div>
    <div class="hiddenstuff">
      You see me now
    </div>
    <p><a href="#" class="link" onclick="showhide(this);">show</a></p>
  </div>

</div>
ikiK
  • 6,328
  • 4
  • 20
  • 40
  • el.forEach(element => { radioId = element.id }); This part is throwing a syntax error in IE11. – Mia Sno Sep 10 '20 at 20:08
  • @MiaSno I really don't see reason why it should. element.id is obliviously well supported, https://developer.mozilla.org/en-US/docs/Web/API/Element/id as well as Array.prototype.forEach https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach as you can see in on links, they both have IE support. Please make sure you don't have illegal characters inside. Or ty to use some other looping technique from this well documented topic: https://stackoverflow.com/questions/3010840/loop-through-an-array-in-javascript . I am on Mac OS now, So i can not test it. – ikiK Sep 10 '20 at 20:26
  • it's the arrow annotation that is not supported :) – Mia Sno Sep 10 '20 at 20:40
  • I think I can use a polyfill for the forEach but for the arrow annotation I have to refactor that without arrow annotation. ugh nevermind forEach IE11 doesn't like either. https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach – Mia Sno Sep 10 '20 at 21:02
  • @MiaSno well I dont like old IE's ;) anyways if you really must support it you can allways use first option 1. Sequential for loop from link I provided. – ikiK Sep 10 '20 at 22:22