jQuery FAQ Expand/contract

I've seen some code out there for this, but I've not managed to Google anything I like. My version uses HTML's Definition Lists. <DL>, <DT> and <DD>. Click on one of the questions below to see it in action.

N.B. Thanks to Peter Boughton's comment. Though I try using next() and it wasn't working for me, hence the ID hack I did have. Anyway, thanks Pete.

Question 1
FAQ Answer 1: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam malesuada urna non ipsum. Integer quis pede. Nulla tincidunt. Sed venenatis semper justo.
Question 2
FAQ Answer 2: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam malesuada urna non ipsum. Integer quis pede. Nulla tincidunt. Sed venenatis semper justo.
Question 3
FAQ Answer 3: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam malesuada urna non ipsum. Integer quis pede. Nulla tincidunt. Sed venenatis semper justo.
Question 4
FAQ Answer 4: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam malesuada urna non ipsum. Integer quis pede. Nulla tincidunt. Sed venenatis semper justo.
Question 5
FAQ Answer 5: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam malesuada urna non ipsum. Integer quis pede. Nulla tincidunt. Sed venenatis semper justo.

Here's the code. I've put remarks in the comments on how it works

view plain print about
1<script src="/jquery/jquery-1.2.6.min.js" type="text/javascript"></script>
2
3<script type="text/javascript">
4    $(document).ready(function(){
5        $("dt").click(function () {
6            $('dd:visible').slideUp('fast');
7            $(this).next('dd').slideDown('fast');
8        });
9    });
10</script>
11
12
13<style>
14    /* Hide all DD's at the start*/
15    dd{display:none;}
16</style>
17
18<!-- Some FAQ Questions -->
19<cfoutput>
20<dl>
21    <cfloop from="1" to="5" index="i">
22        <dt class="q#i#">Question #i#</dt>
23        <dd id="q#i#">FAQ Answer #i#: Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam malesuada urna            non ipsum. Integer quis pede. Nulla tincidunt. Sed venenatis semper justo.</dd>
24    </cfloop>
25</dl>
26</cfoutput>

Posted: 04-Sep-2008

View: 7416

Permalink: here

Comments

No need for that id/class hack.

This works just fine:
$('dd:visible').slideUp('fast');
$(this).next('dd').slideDown('fast');

#1 Peter Boughton
04/Sep/08 6:18 PM

@Peter, You know I was playing around with Next() but it wasn't working for me. Thats why I put that hack in. Your code worked fine so God know what I was doing beforehand! Thanks

#2 Andy Jarrett
04/Sep/08 7:07 PM

For accessibility reasons it's a good idea to hide the your dd tags using jQuery instead of the style sheet. That way users who don't have JavaScript enabled will see all dd tags and those with JavaScript enabled will have them hidden. So you code would be:

$(document).ready(function(){
$('dd').hide();
$("dt").click(function () {
$('dd:visible').slideUp('fast');
$(this).next('dd').slideDown('fast');
});
});

#3 John Whish
05/Sep/08 4:18 AM

It doesn't degrade. If javascript is disabled, nothing is displayed.

I recommend checking out this technique:
http://www.tjkdesign.com/articles/toggle_elements....

- It uses semantic markup.
- It degrades nicely (hidden elements are visible in script-disabled UAs).
- DTs do not appear as links without script support.
- It does not use inline event attribute (onclick()).
- It does not require A elements in the markup.
- It is screen-readers "friendly".
- It is keyboard "friendly".
- It is IE Mac compatible.
- It relies on one single hook.
- It allows the author to add/move/delete DT/DD pairs easily (there is no variable in the script to edit and there are no class or ID to include nor change).
- It is "powered" by a very light script (3Kb).

#4 James Moberg
05/Sep/08 9:37 AM

@james - i think what is attractive about this solution is that it is incredibly lightweight, its based on jquery, its semantic and by adding an id or class (something like <body id="nojs">) to your body tag, you could simply use jquery to remove the class or id attribute. you could then override the css so everything is displayed properly.

mine looks something like this:

javascript:
$(function(){
$("body").removeAttr('id');
$("#faq dt").click(function () {
$('#faq dd:visible').slideUp('fast');
$(this).next('dd').slideDown('fast');
});
});

css:
#faq dd{
display: none;
}
body#nojs #faq dd{
display: block;
}

#5 Chris Rault
27/Jan/09 4:35 AM