1

I have 4 elements and within onclick() only one of the block div will show;

HTML:

<!--elements that will toggle block div to show-->
<p onclick="expand(this.id)" id="p1"></p>
<p onclick="expand(this.id)" id="p2"></p>
<p onclick="expand(this.id)" id="p3"></p>
<p onclick="expand(this.id)" id="p4"></p>
<!--block div-->
<div id="block_p1"></div>
<div id="block_p2"></div>
<div id="block_p3"></div>
<div id="block_p4"></div>

JS:

function expand(e) {
document.getElementById("block_" + e).style.display = "block";
document.getElementById(e).style.backgroundColor = "#425a94";
}

The problem is when I click the second element after the first, says I click p2 after p1, the block div--block_p1 doesn't disappear as block_p2 is shown, how do I hide the first block after the second is clicked? If I didn't use the parameter I'd do something like this:

function expand() {
document.getElementById("block_p2").style.display = "block";
document.getElementById("p2").style.backgroundColor = "#425a94";
document.getElementById("block_p1").style.display = "none";
}

I don't know how to do the same in the case of the one with a parameter. Also in the case that third element is selected I need to hide the first two blocks as well.

pploypiti
  • 59
  • 1
  • 9

3 Answers3

5

You first need to hide all divs that start with id expanded_, just add this line before rest of your code.

var allExpanded = document.querySelectorAll( "div[id^='expanded_']" );
Array.from( allExpanded ).forEach( s => (s.style.display = "none") );

Your functions becomes

function expand(e) 
{
    //first hide all
    var allExpanded = document.querySelectorAll( "div[id^='expanded_']" );
    Array.from( allExpanded ).forEach( s => (s.style.display = "none") );
    //then show specific
    document.getElementById("expanded_" + e).style.display = "block";

    document.getElementById(e).style.backgroundColor = "#425a94";
    document.getElementById("toolbar_expand").style.display = "block";
}
gurvinder372
  • 66,980
  • 10
  • 72
  • 94
  • `"div[id^='expanded_']"` is just the worst thing I've ever seen. It's like you're 100% sure there won't be any other divs with IDs in the document, which is statistically wrong. – ibrahim mahrir Apr 23 '18 at 11:03
  • @ibrahimmahrir It is okay for this question though... I use selectors like that sometimes, if ID's are named like they should, there would not be any danger in 'being 100% sure there won't be any other divs with ID's like that in the document'. (although 'expanded_' is rather general and could be used somewhere else...) – Brainfeeder Apr 23 '18 at 11:07
  • 1
    @Brainfeeder Fair enough. Although a (specially picked) class would've been better. – ibrahim mahrir Apr 23 '18 at 11:11
  • 1
    @ibrahimmahrir === (bool)true – Brainfeeder Apr 23 '18 at 11:12
1

From my previous answer, a small amendment to pick up all display elements which can be looped over in the function to remove the class that was previously added:

const buttons = document.querySelectorAll('.button');
const slides = document.querySelectorAll('.slide');

buttons.forEach(button => {
  button.addEventListener('click', handleClick, false);
});

function handleClick(e) {
  const id = e.target.dataset.id;
  slides.forEach(slide => slide.classList.remove('show'));
  const slide = document.querySelector(`.slide[data-id="${id}"]`);
  slide.classList.add('show');
}
.slide {
  display: none;
}

.show {
  display: block;
}
<p class="button" data-id="1">icon1</p>
<p class="button" data-id="2">icon2</p>
<p class="button" data-id="3">icon3</p>
<div class="slide" data-id="1">blocki1</div>
<div class="slide" data-id="2">blocki2</div>
<div class="slide" data-id="3">blocki3</div>
Andy
  • 61,948
  • 13
  • 68
  • 95
0

You can use the id match selector to get all the div with id having block_ as substring and then hide all of them except the clicked one.

function expand(id) {
  document.getElementById('block_'+id).style.display = "block";
  document.getElementById(id).style.backgroundColor = "#425a94";
  document.querySelectorAll('[id^="block_"]').forEach(function(elem){
   if(elem.id !== 'block_'+id){
     elem.style.display = "none";
     var pId = elem.id.split('_')[1];
     document.getElementById(pId).style.backgroundColor = "#fff";
   }
  });
}
div{
 display: none;
}
<!--elements that will toggle block div to show-->
<p onclick="expand(this.id)" id="p1">p1 click</p>
<p onclick="expand(this.id)" id="p2">p2 click</p>
<p onclick="expand(this.id)" id="p3">p3 click</p>
<p onclick="expand(this.id)" id="p4">p4 click</p>
<!--block div-->
<div id="block_p1">P1</div>
<div id="block_p2">P2</div>
<div id="block_p3">P3</div>
<div id="block_p4">P4</div>
Ankit Agarwal
  • 30,378
  • 5
  • 37
  • 62