Web Development optimize

How to create an expandable and contractible FAQ in jQuery

Ryan Boudreaux demonstrates how you can use jQuery's toggle function to create a website FAQ that is expandable and contractible.

Continuing in our tutorial series of introducing jQuery functions and features, I will demonstrate how to creating an expanding and contracting FAQ document using the toggle .toggle() function in jQuery.

If you have missed the first four parts of the jQuery series, be sure to check them out below, as they set the foundation for the continuation of steps we will take in this segment:

The demonstrations, including the index.html file, are all contained in the download, so you can follow along in the steps below to create your own updates as we progress.

Create an expandable and contractible FAQ

The power of jQuery will be leveraged to create a nifty FAQ with questions that always show, but the answers are expandable upon click and contractible as well. In addition, we will add in a feature to expand all answers and contract all answers as well, since by default on page load, the answers are hidden. This feature gives visitors the option of viewing answers to questions which pertain to their inquiry only, and helps to clean up especially long FAQ sections.

We will start with adding a definition list into the body of our index.html (located in the download) starting with adding in our FAQ section on line 13 as displayed below. This is a semantic form to show the questions and answers; though jQuery does not require it, we have the questions inside the definition term <dt> tags, and the answers in the definition description <dd> tags.

   <section class="FAQ">
     <p>Frequently Asked Questions</p>
       <dl>
         <lh>FAQ - Section 1</lh>
          <dt>Question 1</dt>
           <dd>This is the answer to the first question.</dd>
          <dt>Question 2</dt>
           <dd>This is the answer of the second question.</dd>
         <lh>FAQ - Section 2</ln>
          <dt>Question 1</dt>
           <dd>This is the answer to the first question.</dd>
          <dt>Question 2</dt>
           <dd>This is the answer of the second question.</dd>
       </dl>
   </section>

View the FAQ section in your browser; below is how it looks in Chrome 18.0.1:

Figure A

Next, we will add in the following .hide() function to within our document ready function to hide all definition descriptions as shown below. This one call will hide all the <dd> tags in the document, making them disappear upon document ready. Placing the following line of code within the document ready function:

        $("dd").hide();

Now, all our answers are hidden. Now view the index.html document in your browser and refresh the page, only the definition headers and questions are shown as displayed in Chrome 18.0.1:

Figure B

Next, we will make the questions clickable, which will allow users to view the answers once they click on a question. To do this, we need to add the .click(function) to the <dt> tags, and we will also make a call to some CSS as well. We will then grab every <dt> tag using the $(this).next() function along with a .toggle() function to our jQuery document ready function. Add the following jQuery to the document ready function:

        $("dt") .addClass('question') .click(function() {
          $(this).next().toggle();
        });

The real power of jQuery is the leverage you get with the second line of code listed above (I will explain why just a bit further along). First, let's add in the styling that is called from the .addClass(‘question').

This CSS styling is added to the styles.css file:

.question {
       cursor: pointer;
       color: #696;
       font-weight:bold;
}

When the document is ready, the jQuery calls the pointer curs0r, and sets the <dt> tags to a color of #696, and a font weight of bold, also adding in a click function and applying the same to all subsequent sibling <dt> tags in the document. Then upon click, the visibility of the <dd> tag is toggled to appear, click again, and the toggle has the <dd> tag disappear.

You may wonder how the <dd> tags are referenced? Remember, I mentioned above that one importation line of code. We originally set all the <dd> tags to hidden, and for the object <dt> tags, we reference them with the $(this) function. Then, we call the .next() function on the clicked object to return the object that immediately comes after it in the HTML, and finally we have the .toggle() which allows us to toggle the visibility from hidden to show.

Refresh your index.html file and play around with clicking on a question. This is our FAQ as displayed in Chrome 18.0.1:

Figure C

This is the FAQ displayed after the first question is clicked:

Figure D

Expansion plans

If you want to allow visitors to expand all the answers at once for the FAQ questions, it's an easy edit. All we need to do is add in a link to click, which will show all the answers. We will be using the .toggle() and .show() function again to the <dd> tags.

Add in this jQuery to the document ready function, and place it above the <dd> .hide() function:

$(".FAQ").prepend('<a href="#" id="show">Expand all FAQ answers</a>');
Then, add this code to the bottom of the document ready function:
        $("#show").click(function () {
          $("dd").show();
        });
Refresh the index.html file in your browser and then click on the link "Expand all FAQ answers"; the result is displayed in Figure E below:

Figure E

Now, do you want the users to have the ability to expand (show) and contract (hide) all the answers with just one click? Easy -- we will update one entry and use the same link, but instead of calling the $("dd").show(); we will replace that with this line:

          $("dd").toggle();

Then, update the link to this:

$(".FAQ").prepend('<a href="#" id="show">Show/Hide all FAQ answers</a>');

Now, refresh the index.html page and the first click on the link "Show/Hide all FAQ answers" will make them all visible; click on the same link again, and it will make them disappear.

You can also add in a separate Expand and Contract buttons, or name them "Show All" and "Hide All". To do so, we will add in the following buttons within the FAQ section:

   <input type="button" id="show_dd" value="Show All" />
   <input type="button" id="hide_dd" value="Hide All" />

Then we will add in the following jQuery within the document ready function at the bottom:

        $("#show_dd").click(function () {
          $("dd").show();
        });
        $("#hide_dd").click(function () {
          $("dd").hide();
        });

Refresh the index.html document and the following is displayed as shown in Chrome 18.0.1:

Figure F

Click on the Show All button and the result is the same as the "Expand All FAQ Answers" link shown in Figure E. Click on the Hide All button, and the answers disappear.

About

Ryan has performed in a broad range of technology support roles for electric-generation utilities, including nuclear power plants, and for the telecommunications industry. He has worked in web development for the restaurant industry and the Federal g...

2 comments
fbenitez
fbenitez

On this line: FAQ - Section 2 I think the closing markup must be And thanks for publishing this tutorial series.

RJBoudreaux
RJBoudreaux

You are correct, the closing should be </lh > Must have fat fingered the ln Thanks for posting the error!