DotNetCurry Logo

Extending the jQuery UI Accordion

Posted by: Suprotim Agarwal , on 5/19/2014, in Category jQuery and ASP.NET
Views: 12224
Abstract: This article demonstrates how to extend the jQuery UI Accordion by creating resizable panels.

The jQuery UI accordion allows you to organize related content into distinct sections, with any one section visible at a time. The collapsed sections are revealed by clicking on the corresponding section heading. The jQuery UI accordion is very easy to setup and configure.

This article is taken from my upcoming The Absolutely Awesome jQuery Cookbook at www.jquerycookbook.com

Download the source code which contains the jQueryUIAccordion.html in it. This html already contains the library references to the jQuery theme CSS, jQuery library, jQuery UI library and some underlying markup.

Here’s a preview of the HTML markup:




    Simple jQuery UI Accordion
   
   
   



   


       

What Does This Book Contain?


       


            Scores of practical jQuery recipes that you can use in your projects.
       


       

       

Where can I download Sample chapters?


       

You can download sample chapters over here.

       

Who is the Book Author?


       


            Suprotim Agarwal is the author of this Book.
       


   


The outer container ‘

’ has an id of ‘faq’. The heading of the accordion has a ‘

’ element and the content section has a para ‘

’ as a container. The content section can contain any kind of data. In order to make an accordion of this markup, just add a single line of jQuery code:


and that’s it. You have an Accordion control!

You can pass some configuration options to change the way the default accordion behaves. To set configuration options, we will pass an object literal into the accordion as shown below:

$(function () {
    $("#faq").accordion({
        "optionname": "value"
    });
});

For example, the Accordion sets an equal height for all the Panels by setting the heightStyle to auto, which means all panels will be of the same height as the tallest panel. This leads to extra whitespace in those content panels where the content is less

s3-accordion-whitespace

In order to fix this, set the heightStyle to content which means each panel will be only as tall as its content.

$("#faq").accordion({
    event: "mouseover",
    collapsible: true,
    active: 2,
    heightStyle: 'content'
});

View the page in the browser and you will see that the 2nd panel is now only high enough to contain its own content.

s3-accordion-whitespace-fixed

Extending the jQuery UI Accordion

We just saw how to save whitespace by using the heightStyle property to enable the panel to be only as tall as its content.

Alternatively we can also extend the existing jQuery UI Accordion widget and provide a consistent way for users to enable/disable resize functionality. We will extend the jQuery UI Accordion to provide users with the option to drag and resize the content panel.

Understanding the jQuery UI Widget Factory

The jQuery UI Widget Factory is simply a function or factory method ($.widget) on which all of jQuery UI's widgets are built. It takes the widget name and an object containing widget properties as arguments and creates a jQuery plugin - that provides a consistent API to create and destroy widgets, encapsulate its functionality, allow setting options on initialization and provide state management. In simple words, it allows you to conform to a defined standard, making it easier for new users to start using your plugin.

Note: All jQuery UI's widgets use the same patterns as defined by the widget factory. If you learn how to use one widget, you'll know how to use all of them.

Creating a Widget Extension

You can create new widgets with the widget factory by passing the widget name and prototype to $.widget().

$.widget("custom.newAccordion", {});

This will create a newAccordion widget in the custom namespace.

However in our case, we want to extend the existing Accordion widget. To do so, pass the constructor of the jQuery UI Accordion widget ($.ui.accordion) to use as a parent, as shown here:

$.widget("custom.newAccordion", $.ui.accordion, {});

By doing so, we are indicating that the newAccordion widget should use jQuery UI's Accordion widget as a parent. In order to make our new widget useful, we will add some methods to its prototype object, which is the final parameter passed to $.widget(). The shell of our widget will look similar to the following:

(function ($) {
    $.widget("custom.newAccordion", $.ui.accordion, {
        options: {           
        },
        _create: function () {
        },
        destroy: function () {
        },
        disable: function () {
        },
        enable: function () {
        },
    });
})(jQuery);

Note: If you observe, the jQuery UI plugin has been encapsulated in a self-executing anonymous function (function ($) {}). This aliases $ and ensures that jQuery's noConflict() method works as intended.

Let’s add some functionality to our widget. Observe the following code:

(function( $ ) {
$.widget( "custom.newAccordion", $.ui.accordion, {
    options: {
        resizable: true
    },
    _create: function () {
        this._super();
        if ( !this.options.resizable ) {
            return;
        }
        this.headers.next().resizable({ handles: "s" })
        .css({
            "margin-bottom": "5px",
            "border-bottom":"1px dashed",
            "overflow": "hidden"
        });
    },
    _destroy: function () {
        this._super();
        if (!this.options.resizable) {
            return;
        }
        this.headers.next()
        .resizable("destroy")
        .css({
            "margin-bottom": "2px",
            "border-bottom": "1px solid",
            "overflow": ""
        });
    },
});
})(jQuery);

We start by providing flexible configuration through options and initialize them with default values. In this case, we are setting resizable to true by default. The _create() method is the widget’s constructor. In this method, we are replacing the original _create() method with our new implementation. this_super() ensures that the default setup actions of the accordion widget happens.

Note: Widget properties which begin with an underscore such as _create, are considered private.

The next step is to find all content sections of the accordion and apply the resizable() widget.

this.headers.next().resizable({ handles: "s" })

The “s” handle redirects the resizable widget to only show a south handle which means the user can use the cursor at the bottom of each Accordion section to resize it up or down.

We are also using some CSS to set the margin-bottom and border-bottom and overflow properties. Instead of adding CSS properties manually, you can even use a class like this

this.headers.next().resizable({ handles: "s" }).addClass( "mycss" );

The destroy() method removes the widget functionality and returns the element back to its pre-init state.

The final step is to call our newAccordion widget on the faq div and passing resizable to true

$(function () {
    $("#faq").newAccordion(     
        { resizable: true }
    );
});

Run the example and you will see the following Accordion with a dashed bottom border, 5px spacing and a resizable panel:

s3-accordion-custom

You can resize the panel by placing the cursor at the bottom of each section and dragging it up and down to suit your needs:

s3-accordion-custom-resize

Further Reading: http://api.jqueryui.com/jQuery.widget

Download the entire source code of this article (Github)

Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+
Further Reading - Articles You May Like!
Author
Suprotim Agarwal, MCSD, MCAD, MCDBA, MCSE, is the founder of DotNetCurry, DNC Magazine for Developers, SQLServerCurry and DevCurry. He has also authored a couple of books 51 Recipes using jQuery with ASP.NET Controls and a new one recently at The Absolutely Awesome jQuery CookBook.

Suprotim has received the prestigious Microsoft MVP award for nine times in a row now. In a professional capacity, he is the CEO of A2Z Knowledge Visuals Pvt Ltd, a digital group that represents premium web sites and digital publications comprising of Professional web, windows, mobile and cloud developers, technical managers, and architects.

Get in touch with him on Twitter @suprotimagarwal, LinkedIn or befriend him on Facebook



Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!