Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatically close all the other <details> tags after opening a specific <details> tag

Tags:

Here is my code.

<details>
  <summary>1</summary>
  Demo 1
</details>

<details>
  <summary>2</summary>
  Demo 2
</details>

<details>
  <summary>3</summary>
  Demo 3
</details>

What I want to do is -- if the details of any single <details> tag is open and I open/view another <details> tag, then the earlier one should close/hide/minimize.

How can this be achieved?

I'm aware the <details> tag is not supported in IE or Edge.

like image 748
rohan_vg Avatar asked May 25 '13 15:05

rohan_vg


2 Answers

Another approach, slightly shorter, slightly more efficient, without dependencies, and without onclick attributes in the HTML.

// Fetch all the details element.
const details = document.querySelectorAll("details");

// Add the onclick listeners.
details.forEach((targetDetail) => {
  targetDetail.addEventListener("click", () => {
    // Close all the details that are not targetDetail.
    details.forEach((detail) => {
      if (detail !== targetDetail) {
        detail.removeAttribute("open");
      }
    });
  });
});
<details>
  <summary>1</summary>Demo 1
</details>

<details>
  <summary>2</summary>Demo 2
</details>

<details>
  <summary>3</summary>Demo 3
</details>
like image 119
Quentin Roy Avatar answered Sep 22 '22 09:09

Quentin Roy


Whao ! before my posting...

  1. No one has ndicated that <details> elements work with the toggle event?
    -- instead of click
    -- and the toggle event also works with keyboard interaction.

  2. No one has indicated that the open attribute is a boolean,
    make it to true or false, don't do a .removeAttr("open") ;)

the doc : https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details

const All_Details = document.querySelectorAll('details');

All_Details.forEach(deet=>{
  deet.addEventListener('toggle', toggleOpenOneOnly)
})

function toggleOpenOneOnly(e) {
  if (this.open) {
    All_Details.forEach(deet=>{
      if (deet!=this && deet.open) deet.open = false
    });
  }
}
<details>
  <summary>1</summary>
  Demo 1
</details>

<details>
  <summary>2</summary>
  Demo 2
</details>

<details>
  <summary>3</summary>
  Demo 3
</details>

The same thing in a shorter way with ES10? => .ontoggle direct event method

document.querySelectorAll('details').forEach((D,_,A)=>{
  D.ontoggle =_=>{ if(D.open) A.forEach(d =>{ if(d!=D) d.open=false })}
})

See it in action : ( Plus some CSS improvements ;)

document.querySelectorAll('details').forEach((D,_,A)=>{
  D.ontoggle =_=>{ if(D.open) A.forEach(d =>{ if(d!=D) d.open=false })}
})
details {
  border        : 1px solid lightgrey;
  width         : 24em;
  padding       : 0 .6em;
  border-radius : .3em;
  margin        : .3em;
  }
details > summary  {
  font-weight   : bold;
  margin        : 0em -.6em;
  list-style    : none;
  display       : block;
  padding       : .5em;
  }
details[open] {
  padding-bottom : .6em;
  }
details[open] summary {
  border-bottom : 1px solid #aaa;
  margin-bottom : .6em  ;
  }
summary::marker {
  display : none;
  }
summary::-webkit-details-marker {
  display : none;
  }
summary::after {
  display    : block;
  float      : right;
  content    : '\1405';
  cursor     : pointer;
  transition : 180ms;
  transform  : rotate(90deg);
  }
details[open] > summary:after {
  transform  : rotate(-90deg);
  }
summary:hover {
  outline          : none;
  background-color : whitesmoke;
  }
<details>
  <summary>Lorem ipsum one</summary>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, 
  dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas 
  ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, 
  enim est eleifend mi, non fermentum diam nisl sit amet erat.
</details>
<details>
  <summary>Lorem ipsum two</summary>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, 
  dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas 
  ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, 
  enim est eleifend mi, non fermentum diam nisl sit amet erat.
</details>
<details>
  <summary>Lorem ipsum three</summary>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, 
  dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas 
  ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, 
  enim est eleifend mi, non fermentum diam nisl sit amet erat.
</details>
like image 43
Mister Jojo Avatar answered Sep 24 '22 09:09

Mister Jojo