Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to close a detail tag automatically as one of their siblings is opened?

Hi,

this code below closes all other detail tags open if one of them gets opened

document.addEventListener('click', function (e) {
 const details = [...document.querySelectorAll('details')];
 if (!details.some(f => f.contains(e.target))) {
     details.forEach(f => f.removeAttribute('open'));
 } else {
     details.forEach(f => !f.contains(e.target) ? f.removeAttribute('open') : '');
 }
});

Thats fine but I want to modify it so it will only close detail tags next to each other (siblings)

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

document.addEventListener('click', function (e) {
     const details = [...document.querySelectorAll('details')];
      details.some(f => {
       if(f.previousElementSibling && f.previousElementSibling.contains(e.target) || f.nextElementSibling && f.nextElementSibling.contains(e.target)) {
        details.forEach(f => f.removeAttribute('open'));
       } 
      }); 
    });
<details>
 <summary>Parent 1</summary>
 <details><summary>Child 1</summary>opened</details>
 <details><summary>Child 2</summary>opened</details>
 <details><summary>Child 3</summary>opened</details>
</details>
<details>
 <summary>Parent 2</summary>
 <details><summary>Child 1</summary>opened</details>
 <details><summary>Child 2</summary>opened</details>
 <details><summary>Child 3</summary>opened</details>
</details>
<details>
 <summary>Parent 3</summary>
 <details><summary>Child 1</summary>opened</details>
 <details><summary>Child 2</summary>opened</details>
 <details><summary>Child 3</summary>opened</details>
</details>

but I dont have it down right quite yet (clicking on the child will close its parent which I dont intend).

Goal: you click parent 1 and then child 1, then you click child 2, that should close child 1. Then you click parent 2, which should close parent 1 but its child 2 should remain open.

What is missing?

Thank you.

>Solution :

I think it my be easier if you don’t start at document.

const details = document.querySelectorAll('details')

function close_slblings() {
  for (let sib of this.parentElement.querySelectorAll(':scope > details'))
    if (sib != this)
      sib.removeAttribute('open')
      // optionally recursively close their children details
}

for (let el of details) {
  el.addEventListener('click', close_slblings)
}
details{padding-left: 1em;}
<details>
 <summary>Parent 1</summary>
 <details>
   <summary>Parent 1-1</summary>
   <details><summary>Child 1-1-1</summary></details>
   <details><summary>Child 1-1-2</summary></details>
   <details><summary>Child 1-1-3</summary></details>
 </details>
 <details><summary>Child 1</summary></details>
 <details><summary>Child 2</summary></details>
 <details><summary>Child 3</summary></details>
</details>
<details>
 <summary>Parent 2</summary>
 <details><summary>Child 1</summary></details>
 <details><summary>Child 2</summary></details>
 <details><summary>Child 3</summary></details>
</details>
<details>
 <summary>Parent 3</summary>
 <details><summary>Child 1</summary></details>
 <details><summary>Child 2</summary></details>
 <details><summary>Child 3</summary></details>
</details>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading