Accordion - jQuery UI - Web Development with jQuery (2015)

Web Development with jQuery (2015)

Part II. jQuery UI

Chapter 15. Accordion

So far you've learned about how jQuery makes dragging and dropping easy to implement, and you've learned how jQuery makes it a breeze to select items by drawing a box. You've also seen how ridiculously easy it is to implement drag-and-drop sorting with jQuery. This chapter presents another cool jQuery UI plugin, Accordion.

The jQuery UI Accordion plugin makes it easy to implement content that expands and folds like your favorite polka instrument, the accordion. Accordion UI widgets can be seen on popular websites. If you'd like to see a quick demo of the Accordion UI, look atwww.jqueryui.com/accordion/. The downside of the jQuery UI Accordion plugin is that you can have only one item open at a time. It's easy to write some code that sidesteps this limitation.

In this chapter, you find out how to use the jQuery UI Accordion plugin to make your own Accordion widget and customize its look.

Building an Accordion UI

This section discusses how to make an Accordion UI, which is a collection of content panes that each has its own header, where only one content pane is visible at a time. When you click the other content panes, a smooth animation transitions the visible pane to closed by animating its height, leaving only its header visible, animating the other element's height, expanding that element until it is fully visible.

Now that we have briefly explained what an Accordion UI is, the following document, which can be retrieved from www.wrox.com/go/webdevwithjquery as Example 15-1, begins with a basic implementation of the jQuery UI Accordion plugin:

<!DOCTYPE HTML>

<html xmlns='http://www.w3.org/1999/xhtml'>

<head>

<meta http-equiv='content-type'

content='application/xhtml+xml; charset=utf-8' />

<meta http-equiv='content-language' content='en-us' />

<title>Accordion Plugin</title>

<script src='../jQuery.js'></script>

<script src='../jQueryUI.js'></script>

<script src='Example 15-1.js'></script>

<link href='Example 15-1.css' rel='stylesheet' />

</head>

<body>

<h4>The Beatles</h4>

<ul>

<li>

<a href='#'>John Lennon</a>

<p>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

Vestibulum luctus rutrum orci. Praesent faucibus tellus

faucibus quam. Aliquam erat volutpat. Nam posuere.

</p>

</li>

<li>

<a href='#'>Paul McCartney</a>

<p>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

Vestibulum luctus rutrum orci. Praesent faucibus tellus

faucibus quam. Aliquam erat volutpat. Nam posuere.

</p>

</li>

<li>

<a href='#'>George Harrison</a>

<p>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

Vestibulum luctus rutrum orci. Praesent faucibus tellus

faucibus quam. Aliquam erat volutpat. Nam posuere.

</p>

</li>

<li>

<a href='#'>Ringo Starr</a>

<p>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

Vestibulum luctus rutrum orci. Praesent faucibus tellus

faucibus quam. Aliquam erat volutpat. Nam posuere.

</p>

</li>

</ul>

</body>

</html>

The following style sheet is applied to the preceding markup document:

body {

font: 12px "Lucida Grande", Arial, sans-serif;

background: #fff;

color: rgb(50, 50, 50);

margin: 0;

padding: 0;

}

h4 {

margin: 5px;

}

ul {

list-style: none;

margin: 0;

padding: 15px 5px;

}

li {

background: gold;

padding: 3px;

width: 244px;

margin: 1px;

}

The following script makes the <ul> element in the markup document into an accordion with a simple function call:

$(document).ready(

function()

{

$('ul').accordion();

}

);

Figure 15.1 shows that although the accordion has been created, your work here is not yet done.

image

Figure 15.1

You see the most basic but functioning example of the Accordion plugin possible. By calling the accordion() method on the <ul> element, the <ul> element is transformed into accordion UI. When you click an <a> element, the corresponding text in the sibling <p>element is expanded by a smooth, animated transition.

Structurally speaking, jQuery's Accordion plugin wants to be applied to a collection of elements; like a <ul> element, after the plugin is applied, it automatically recognizes each <a> element as being the header portion of each content pane. Later this chapter discusses in more detail how to approach styling an accordion.

Changing the Default Pane

At this point, you have a functioning Accordion UI. This section shows you how to change the content pane that's displayed by default. Out-of-the-box, the Accordion plugin displays the first content pane, but using the active option, you can force a different content pane to be displayed. The following markup document, which appears as Example 15-2 in the source materials, demonstrates this concept:

<!DOCTYPE HTML>

<html xmlns='http://www.w3.org/1999/xhtml'>

<head>

<meta http-equiv='content-type'

content='application/xhtml+xml; charset=utf-8' />

<meta http-equiv='content-language' content='en-us' />

<title>Accordion Plugin</title>

<script src='../jQuery.js'></script>

<script src='../jQueryUI.js'></script>

<script src='Example 15-2.js'></script>

<link href='Example 15-2.css' rel='stylesheet' />

</head>

<body>

<h4>The Beatles</h4>

<ul>

<li>

<a href='#'>John Lennon</a>

<p>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

Vestibulum luctus rutrum orci. Praesent faucibus tellus

faucibus quam. Aliquam erat volutpat. Nam posuere.

</p>

</li>

<li>

<a href='#'>Paul McCartney</a>

<p>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

Vestibulum luctus rutrum orci. Praesent faucibus tellus

faucibus quam. Aliquam erat volutpat. Nam posuere.

</p>

</li>

<li>

<a href='#'>George Harrison</a>

<p>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

Vestibulum luctus rutrum orci. Praesent faucibus tellus

faucibus quam. Aliquam erat volutpat. Nam posuere.

</p>

</li>

<li>

<a href='#'>Ringo Starr</a>

<p>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

Vestibulum luctus rutrum orci. Praesent faucibus tellus

faucibus quam. Aliquam erat volutpat. Nam posuere.

</p>

</li>

</ul>

</body>

</html>

The following style sheet is applied to the preceding markup document:

body {

font: 12px "Lucida Grande", Arial, sans-serif;

background: #fff;

color: rgb(50, 50, 50);

margin: 0;

padding: 0;

}

h4 {

margin: 5px;

}

ul {

list-style: none;

margin: 0;

padding: 15px 5px;

}

li {

background: gold;

padding: 3px;

width: 244px;

margin: 1px;

}

In the following script, you see that the integer 1 is provided to the active option, which causes the second <li> element in the markup document to be used as the default content pane:

$(document).ready(

function()

{

$('ul').accordion({

active : 1

});

}

);

Figure 15.2 shows that the content under Paul McCartney is now the default content. The active option selects the default content when you provide it a zero offset integer (where zero is the first item, one is the second item, and so on) that represents the item in the collection that you want to select by default. In this case, Paul McCartney is the second item, so 1 is provided as the value to the active option to select that panel.

image

Figure 15.2

You can also set the option active to false, which makes no content open by default. If you set the active option to false, you must also set the collapsible option to true. This is demonstrated in the following script:

$(document).ready(

function()

{

$('ul').accordion({

collapsible : true,

active : false

});

}

);

The preceding script gives you the result of having no pane open by default. This example is available in the source materials as Example 15-3.

When you have no default pane selected by default, when you open a panel, you may notice that the content of each pane overlaps the rest of the accordion, as shown in Figure 15.3.

image

Figure 15.3

This problem can be corrected by specifying the heightStyle option. The heightStyle option takes three possible values: auto, fill, and content. The auto option sets the height of each panel to the height of the tallest panel. The problem with this is that because all panels are hidden when the page is rendered, this makes the height of each panel the height of the header without the additional hidden content. The fill option uses the accordion element's parent element as the basis for height. In the context of this example, that would set the height of each item based on the height of the <body> element. The content option sets the height of each panel based on the height of the content that it contains. The following example reflects changing the script to specify the heightStyle option with the content value:

$(document).ready(

function()

{

$('ul').accordion({

collapsible : true,

active : false,

heightStyle : "content"

});

}

);

The preceding example is available in the source materials as Example 15-4. With the change in the preceding script, each item opens without the content overlapping the other headings, as shown in Figure 15.4.

image

Figure 15.4

In the next section you learn how to change the event that triggers opening each content panel in the accordion collection.

Changing the Accordion Event

Upon setup, Accordion content panes are transitioned when you click a header. You have the option of changing the event that triggers the transition using the event option. The following script shows you how to change the event to a mouseover event from a clickevent:

$(document).ready(

function()

{

$('ul').accordion({

active : 1,

event : 'mouseover'

});

}

);

The preceding modification makes no visible change, so you see a document that looks similar to the one referred to in Figure 15.2. However, when you load it in a browser, you can transition between content panes using a mouseover event instead of a click event.

The preceding example is available in the source materials as Example 15-5 but is not shown here.

Setting the Header Elements

By default, the Accordion uses the <a> element as a header within each <li> element. However, you don't have to use an <a> element as the header; the following example, available in the source materials as Example 15-6, illustrates how to use an <h4> element instead of an <a> element:

<!DOCTYPE HTML>

<html xmlns='http://www.w3.org/1999/xhtml'>

<head>

<meta http-equiv='content-type'

content='application/xhtml+xml; charset=utf-8' />

<meta http-equiv='content-language' content='en-us' />

<title>Accordion Plugin</title>

<script src='../jQuery.js'></script>

<script src='../jQueryUI.js'></script>

<script src='Example 15-6.js'></script>

<link href='Example 15-6.css' rel='stylesheet' />

</head>

<body>

<h4>The Beatles</h4>

<ul>

<li>

<h4>John Lennon</h4>

<p>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

Vestibulum luctus rutrum orci. Praesent faucibus tellus

faucibus quam. Aliquam erat volutpat. Nam posuere.

</p>

</li>

<li>

<h4>Paul McCartney</h4>

<p>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

Vestibulum luctus rutrum orci. Praesent faucibus tellus

faucibus quam. Aliquam erat volutpat. Nam posuere.

</p>

</li>

<li>

<h4>George Harrison</h4>

<p>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

Vestibulum luctus rutrum orci. Praesent faucibus tellus

faucibus quam. Aliquam erat volutpat. Nam posuere.

</p>

</li>

<li>

<h4>Ringo Starr</h4>

<p>

Lorem ipsum dolor sit amet, consectetuer adipiscing elit.

Vestibulum luctus rutrum orci. Praesent faucibus tellus

faucibus quam. Aliquam erat volutpat. Nam posuere.

</p>

</li>

</ul>

</body>

</html>

The following style sheet is applied to the preceding markup document:

body {

font: 12px "Lucida Grande", Arial, sans-serif;

background: #fff;

color: rgb(50, 50, 50);

margin: 0;

padding: 0;

}

ul {

list-style: none;

margin: 0;

padding: 15px 5px;

}

h4,

ul h4,

ul p {

margin: 5px;

}

li {

background: gold;

padding: 3px;

width: 244px;

margin: 1px;

}

In the following script, you change the element that's used as the header for each content pane by providing a selector to the header option, in this case h4, which causes the <h4> element of each <li> element to be used as a header, rather than the <a> element:

$(document).ready(

function()

{

$('ul').accordion({

active : 1,

event : 'mouseover',

header : 'h4'

});

}

);

In the preceding script, take note that you also have to change the selector provided to the header option because now you want to have a content pane that uses an <h4> header to be open by default.

Figure 15.4 demonstrates that the <h4> element is used instead of an <a> element.

Summary

In this chapter, you learned how to create an Accordion UI and the various options that you can use to tweak an Accordion UI implementation. You learned that the Accordion plugin takes a list of elements, such as a <ul> element, and makes the items in that list into smoothly animated content panes, which transition one to the other by animating the height of each item in the list. By default, headers for each content pane are provided as <a> elements, but you can change the header element to something else by supplying a selector to the header option.

The active option can be used to change the default content pane that's displayed when the page first loads. You can also have no default content pane by setting the active option to false and the collapsible option to true. If no default content pane is specified, the first element in the list will be used.

The heightStyle option can each be used to tweak how the Accordion plugin defines the height for each content pane. The auto value takes the highest content and uses that height as the height for all other content panes, which may not always provide the right look and feel.

Finally, the event option is used to change the event that's used to trigger a content pane transition; click is the default event.

NOTE A quick reference of the Accordion plugin and its options appears in Appendix N, “Accordion.”

Exercises

1. Which option would you provide to the accordion() method to change the default content pane?

2. Which option and its values would you consider using to change how the accordion() method handles height?

3. What option would you use to make the accordion() method trigger a content transition using a mouseover event instead of a click event?

4. What option would you use to change the header element to an <h3> element?