Question

I've pieced together a bit of jQuery to control a simple FAQ list.

Click on the Question and the answer is revealed. I've also added an 'Expand all' and 'Minimise all' button. The text for this button changes (via jQuery) depending on whats's required.

This works - but it's not very clever...

Check out the jsFiddle (link below) and click Question 1 and then click the 'Expand all' button (at the top) and you'll see the problem. The open and close states get messed up.

I understand why, I'm using Toggle to control if the answers are shown or not. Toggle will just do the opposite of whatever state the targeted element is in.

Anyone know how to make this better? My jQuery skills are limited at best

Here's a jsfiddle

http://jsfiddle.net/StephenMeehan80/P7WGd/

jQuery $("#FAQs .wrap").hide(); $("#FAQs .close").hide();

// Click the #Expand button to show and hide .wrap (.wrap contains the answers)
$('#Expand').click(function(){
    $('h2').children(".close").toggle();
    $('h2').children(".arrow-down").toggle();
       $('#FAQs .wrap').slideToggle('fast');
       if($(this).text() == 'Minimise FAQs')
       {
           $(this).text('Expand FAQs');
       }
       else
       {
           $(this).text('Minimise FAQs');
       }
       });

// Click the Quesiton (h2) to show and hide the answer
$("#FAQs h2").addClass("link").click(function() {  
$(this).parent().children(".wrap").slideToggle('fast')
$(this).children(".close").toggle();
$(this).children(".arrow-down").toggle();
});

HTML

<div class="faq-controls">
    <span id="Expand">Expand FAQs</span>
</div>
<ul id="FAQs" class="faq">
    <li>
        <h2>
            <span class="arrow-down">⬇</span><span class="close">✖</span>&nbsp;Question 1
        </h2>
        <div class="wrap">
            <p>
                Sed sit amet tempus magna, at blandit purus. Donec pulvinar vulputate nunc, id mollis sem congue sed. Nullam vitae diam eu libero tristique accumsan a vitae nulla. Mauris ut leo eros. In commodo pretium leo eget lobortis. Fusce et metus orci. Nullam semper velit sit amet quam semper commodo. Aenean enim dui, mollis non volutpat vulputate, elementum ut metus. Nulla feugiat tellus massa, tristique fringilla odio commodo et.
            </p>
        </div>
    </li>
    <li>
        <h2>
            <span class="arrow-down">⬇</span><span class="close">✖</span>&nbsp;Question 2
        </h2>
        <div class="wrap">
            <p>
                Sed sit amet tempus magna, at blandit purus. Donec pulvinar vulputate nunc, id mollis sem congue sed. Nullam vitae diam eu libero tristique accumsan a vitae nulla. Mauris ut leo eros. In commodo pretium leo eget lobortis. Fusce et metus orci. Nullam semper velit sit amet quam semper commodo. Aenean enim dui, mollis non volutpat vulputate, elementum ut metus. Nulla feugiat tellus massa, tristique fringilla odio commodo et.
            </p>
        </div>
    </li>
    <li>
        <h2>
            <span class="arrow-down">⬇</span><span class="close">✖</span>&nbsp;Question 3
        </h2>
        <div class="wrap">
            <p>
                Sed sit amet tempus magna, at blandit purus. Donec pulvinar vulputate nunc, id mollis sem congue sed. Nullam vitae diam eu libero tristique accumsan a vitae nulla. Mauris ut leo eros. In commodo pretium leo eget lobortis. Fusce et metus orci. Nullam semper velit sit amet quam semper commodo. Aenean enim dui, mollis non volutpat vulputate, elementum ut metus. Nulla feugiat tellus massa, tristique fringilla odio commodo et.
            </p>
        </div>
    </li>
</ul>
Was it helpful?

Solution

you are using slide toggle, so whatever the current state (open or closed) is when you click the 'all' toggle, will go to the opposite state. use the jquery 'slideup' or 'slidedown' functions instead, to have more control.

http://jsfiddle.net/P7WGd/2/

something like this, you may need to update your class toggles also:

jquery

if($(this).text() == 'Minimise FAQs')
{
   $(this).text('Expand FAQs');
   $('#FAQs .wrap').slideUp('fast');

}
else
{
   $(this).text('Minimise FAQs');
    $('#FAQs .wrap').slideDown('fast');

}

css...

.faq-controls {
  font-size: 0.9em;
  margin-bottom: 1.5em; }

  .faq-controls #Expand, .faq-controls #Minimise {
    color: #3b3b3b;
    border-bottom: 1px solid #3b3b3b;
    cursor: pointer; }

    .faq-controls #Expand:hover, .faq-controls #Minimise:hover {
      color: #ed1b2e;
      border-bottom-color: #ed1b2e; }  

ul.faq {
  list-style: none;
  margin: 1em 0 0 0;
  padding: 0; }

   ul.faq li {
    margin: 0 0 1.3em 0;
    padding: 0 0 1.3em 0;
    border-bottom: 1px solid #d4d4d4; }

     ul.faq li h2.link {
      margin: 0;
      cursor: pointer;
      font-size: 1.1em; }

       ul.faq li h2.link:hover {
        color: #ed1b2e; }

       ul.faq li h2.link span.close,  ul.faq li h2.link span.arrow-down {
        background: #0053a0;
        color: white;
        width: 20px;
        line-height: 20px;
        display: block;
        text-align: center;
        float: left;
        font-size: 0.8em; } 

   ul.faq .wrap {
    display: block; }

html...

<div class="faq-controls">
    <span id="Expand">Expand FAQs</span>
</div>
<ul id="FAQs" class="faq">
    <li>
        <h2>
            <span class="arrow-down">⬇</span><span class="close">✖</span>&nbsp;Question 1
        </h2>
        <div class="wrap">
            <p>
                Sed sit amet tempus magna.
            </p>
        </div>
    </li>
    <li>
        <h2>
            <span class="arrow-down">⬇</span><span class="close">✖</span>&nbsp;Question 2
        </h2>
        <div class="wrap">
            <p>
                Sed sit amet tempus magna.
            </p>
        </div>
    </li>
    <li>
        <h2>
            <span class="arrow-down">⬇</span><span class="close">✖</span>&nbsp;Question 3
        </h2>
        <div class="wrap">
            <p>
                Sed sit amet tempus magna, at blandit purus. Donec pulvinar vulputate nunc, id mollis sem congue sed. Nullam vitae diam eu libero tristique accumsan a vitae nulla. Mauris ut leo eros. In commodo pretium leo eget lobortis. Fusce et metus orci. Nullam semper velit sit amet quam semper commodo. Aenean enim dui, mollis non volutpat vulputate, elementum ut metus. Nulla feugiat tellus massa, tristique fringilla odio commodo et.
            </p>
        </div>
    </li>
</ul>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top