Making summary details element auto collapsible

578 views Asked by At

I've been trying out the summary and details list and can't find a way to make it auto collapse when the next in the list is clicked...

Here the code I have:

HTML:

<div class="content">
                    <header class="major">
                        <h2>Stuff I do</h2>
                    </header>
                    <p>Consequat sed ultricies rutrum. Sed adipiscing eu amet interdum lorem blandit vis ac commodo aliquet vulputate.</p>
                    <ul class="alt">
                        <li>
                            <details><summary><span class="icon major fa-camera-retro"></span>
                            <h3>List item 1</h3><p>Donec accumsan interdum nisi</p></summary>
                            <p>Aliquam ante ac id. Adipiscing interdum lorem praesent fusce pellentesque arcu feugiat. Consequat sed ultricies rutrum. Sed adipiscing eu amet interdum lorem blandit vis ac commodo aliquet integer vulputate phasellus lorem ipsum dolor lorem magna consequat sed etiam adipiscing interdum.</p></details>
                        </li>
                        <li>
                            <details><summary><span class="icon major fa-pencil"></span>
                            <h3>List item 2</h3><p>Donec accumsan interdum nisi</p></summary>
                            <p>Aliquam ante ac id. Adipiscing interdum lorem praesent fusce pellentesque arcu feugiat. Consequat sed ultricies rutrum. Sed adipiscing eu amet interdum lorem blandit vis ac commodo aliquet integer vulputate phasellus lorem ipsum dolor lorem magna consequat sed etiam adipiscing interdum.</p></details>
                        </li>
                        <li>
                            <details><summary><span class="icon major fa-code"></span>
                            <h3>list item 3</h3><p>Donec accumsan interdum nisi</p></summary>
                            <p>Aliquam ante ac id. Adipiscing interdum lorem praesent fusce pellentesque arcu feugiat. Consequat sed ultricies rutrum. Sed adipiscing eu amet interdum lorem blandit vis ac commodo aliquet integer vulputate phasellus lorem ipsum dolor lorem magna consequat sed etiam adipiscing interdum.</p></details>
                        </li>
                        <li>
                            <details><summary><span class="icon major fa-coffee"></span>
                            <h3>List item 4</h3><p>Donec accumsan interdum nisi</p></summary>
                            <p>Aliquam ante ac id. Adipiscing interdum lorem praesent fusce pellentesque arcu feugiat. Consequat sed ultricies rutrum. Sed adipiscing eu amet interdum lorem blandit vis ac commodo aliquet integer vulputate phasellus lorem ipsum dolor lorem magna consequat sed etiam adipiscing interdum.</p></details>
                        </li>
                    </ul>
                </div>

CSS:

details summary::-webkit-details-marker {
display: none;}

summary:hover {
cursor: pointer;
color: #fff200;

}

So when 'list item 1' is opened and 'list item 3' is clicked I want item 1 to automatically collapse again. Help would be very much appreciated!

2

There are 2 answers

3
Ivan Jovović On

Idea

  1. On load, slideUp() all paragraphs inside li, so only headers are visible.
  2. Attach click handler on each header, so once clicked, it slideUp() all other items, and slideDown() the clicked one.

Implementation

Alter html to add clases so jQuery can reference them (class="click" and class="collapsable"):

<li class="click">
  <details><summary><span class="icon major fa-coffee"></span>
    <h3>List item 4</h3><p>Donec accumsan interdum nisi</p></summary>
      <p class="collapsable">Aliquam ante ac id. Adipiscing interdum lorem praesent fusce pellentesque arcu feugiat.

jQuery onload:

$('.collapsable').slideUp();
$( '.click' ).on( "click", function() {
    $('.collapsable').slideUp();
    $('.collapsable', this).slideDown();
});

Working fiddle: http://jsfiddle.net/2mbs4wxp/4/


EDIT

To solve the issue described in comment:

The content is fairly long in some list items, so when next one is clicked and previous collapses it sometimes leaves you at far below the clicked content.

Chain the animate({scrollTop... to the slideDown() event so your clicked div is scrolled to the top of the screen. You just need to alter your jQuery a bit:

$('.collapsable').slideUp();
$( '.click' ).on( "click", function() {
    $('.collapsable').slideUp();
    $('.collapsable', this).slideDown().promise().done(function(){
      $('html,body').animate({scrollTop: $(this).offset().top - 100}, 200);
    });
});

Working Fiddle: http://jsfiddle.net/2mbs4wxp/6/

0
Dave H. On

If you want a pure JavaScript solution, try this:

Put this function in the of your document:

function thereCanBeOnlyOne(elementId) {
  var detailsElements = document.getElementsByTagName('details');
  for (var i=0; i<detailsElements.length; i++) {
    if (detailsElements[i].id != elementId && detailsElements[i].classList.contains('collapsible')) {
      detailsElements[i].removeAttribute('open');
    }
  }
}

And then in your HTML:

1) use the class of 'collapsible' and put an id attribute on the details

2) add the onclick handler to the summary.

<details id="one" class="collapsible" open=true>
<summary onclick="thereCanBeOnlyOne('one');">One</summary>

For a demo see: https://waxphilosophic.sdf.org/webdev/accordian/summary-details-js.html

You can simplify even further if you don't care about marking only certain summary/details as collapsible.