LIDOR SYSTEMS

Advanced User Interface Controls and Components

jQuery Accordion Header with Custom Buttons

Created: 18 August 2014

Accordion is consisting of multiple groups which can expand horizontally or vertically. Each group has a header and a content panel, without any buttons in its header, except for the expand box. We can create a group with custom header containing multiple buttons, using custom HTML elements and CSS styles. In following sections we will demonstrate how to add multiple buttons to each group header with custom functionality.

Group 1

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim.

Group 2

Pellentesque malesuada nulla a mi. Duis sapien sem, aliquet nec, commodo eget, consequat quis, neque. Aliquam faucibus, elit ut dictum aliquet, felis nisl adipiscing sapien, sed malesuada diam lacus eget erat. Cras mollis scelerisque nunc. Nullam arcu. Aliquam consequat.

Group 3

Fusce convallis, mauris imperdiet gravida bibendum, nisl turpis suscipit mauris, sed placerat ipsum urna sed risus. In convallis tellus a mauris. Curabitur non elit ut libero tristique sodales. Mauris a lacus. Donec mattis semper leo. In hac habitasse platea dictumst. Vivamus facilisis diam at odio.

Accordion is part of IntegralUI Studio for Web
a suite of UI Components for development of web apps

At first we need to create the Accordion structure, we can do this either from HTML or through code using jQuery. Here is an example of an Accordion with three groups:

<!DOCTYPE html>

<html>

<head>

<link rel="stylesheet" href="css/integralui.accordion.css" />

<link rel="stylesheet" href="css/themes/theme-light.css" />

<script type="text/javascript" src="external/jquery-1.9.1.min.js"></script>

<script type="text/javascript" src="external/jquery.ui.core.min.js"></script>

<script type="text/javascript" src="external/jquery.ui.widget.min.js"></script>

<script type="text/javascript" src="js/jquery.integralui.widget.min.js"></script>

<script type="text/javascript" src="js/jquery.integralui.accordion.min.js"></script>

</head>

<body>

<div id="accordion" class="widget">

<h3><span>Group 1</span></h3>

<div><p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim.</p></div>

<h3><span>Group 2</span></h3>

<div><p>Pellentesque malesuada nulla a mi. Duis sapien sem, aliquet nec, commodo eget, consequat quis, neque. Aliquam faucibus, elit ut dictum aliquet, felis nisl adipiscing sapien, sed malesuada diam lacus eget erat. Cras mollis scelerisque nunc. Nullam arcu. Aliquam consequat.</p></div>

<h3><span>Group 3</span></h3>

<div><p>Fusce convallis, mauris imperdiet gravida bibendum, nisl turpis suscipit mauris, sed placerat ipsum urna sed risus. In convallis tellus a mauris. Curabitur non elit ut libero tristique sodales. Mauris a lacus. Donec mattis semper leo. In hac habitasse platea dictumst. Vivamus facilisis diam at odio.</p></div>

</div>

</body>

</html>

.i-ui-accordion-header-selected

{

color: #c60d0d;

}

.widget

{

background: transparent;

width: 300px;

height: 300px;

}

.widget > div > p

{

margin: 0;

overflow: hidden;

padding: 5px;

text-overflow: ellipsis;

}

We can modify the appearance of the Accordion by changing its CSS styles; there is a different CSS class for each part. But if we want to further change the appearance of group header for example to add a toolbar with multiple custom buttons, we need to create those elements using HTML.

Related: Accordion with Headers in Different Colors

In our example group header will consist of a title shown to the left side and a set of buttons aligned to the right side. To create a button we will use the tag displayed as inline block. Each button consists of custom small image. Here how this looks like in code:

// Create the group header

var generateGroupHeader = function(index){

var header = "<div class='group-header'>" +

"<div class='toolbar'>" +

"<span class='icons recycle'></span>" +

"<span class='icons lock-open'></span>" +

"<span class='icons delete'></span>" +

"</div>" +

"<span>Header " + index + "</span>" +

"</div>"

 

return header;

}

 

// Suspend the Accordion layout to increase performance

$bar.accordion("suspendLayout");

 

// Add groups to the Accordion

var groups = $bar.accordion("getList");

for (var i = 0; i < groups.length; i++){

// Apply custom HTMl generated content to the headerContent property

groups[i].headerContent = generateGroupHeader(i+1);

// By default set all groups to be selectable

groups[i].locked = false;

}

 

// Resume and update the layout of Accordion

$bar.accordion("resumeLayout");

.group-header

{

position: relative;

}

.group-header span

{

display: inline-block;

}

.toolbar

{

position: absolute;

top: 2px;

left: 226px;

width: 74px;

}

.toolbar span

{

border: thin solid transparent;

border-radius: 1px;

margin: 0 1px;

}

.toolbar span:hover

{

background-color: white;

border-color: #969696;

}

.icons

{

background-image: url(images/accordion-icons.png);

background-repeat: no-repeat;

display: inline-block;

overflow: hidden;

padding: 1px;

margin: 0 1px;

width: 16px;

height: 16px;

}

.empty

{

background-position: 0px 0px;

}

.delete

{

background-position: -17px 0;

}

.lock

{

background-position: -34px 0;

}

.lock-open

{

background-position: -54px 0;

}

.recycle

{

background-position: -72px 0;

}

Note   The locked variable is not part of Accordion widget specification, it's created only for this example to handle clicks from Lock button in our toolbar, which can lock or unlock a group and prevent or allow a group to become selected.

Our code we will change the appearance of existing groups by showing a toolbar consisting of a Recycle, Lock and Delete buttons. Each of these buttons when clicked will perform a different action. A click to:

  • Recycle button, will show a pop-up message stating that the button is clicked
  • Lock button, will lock/unlock the group selection and expansion
  • Delete button, will remove the group from the Accordion

We will create a function which will re-apply the click events for all buttons in each group, whenever the Accordion structure has changed.

At first we will retrieve the list of elements representing header of each group using a tag selector. Then by cycling through each group we can locate its attached toolbar using a class selector. Because buttons are child of group element, any click from a button will also bubble up and handled by internal code event handlers for groups in Accordion. As a result this will select the corresponding group, which we don't want. We want our toolbar to act as a separate component attached to each group header. To solve this we need to stop propagation of clicks upwards.

// Bind the click event for all header buttons

var rebindEvents = function(){

var groupElems = $bar.children("h3");

groupElems.each(function(groupIndex){

 

// Prevent selection of accordion group

var toolbar = $(this).find(".toolbar");

toolbar

.off("mousedown")

.on({

"mousedown": function(e){

e.stopPropagation();

}

});

 

// Find all group buttons and attach the click event

var btns = $(this).find(".icons");

btns.each(function(index){

var currentButton = $(this);

 

currentButton

.off("click")

.on({

"click": function(e){

switch (index){

case 0: // Recycle button

alert("Recycle button clicked for: " + groups[groupIndex].text);

break;

case 1: // Lock Button

groups[groupIndex].locked = !groups[groupIndex].locked;

if (groups[groupIndex].locked)

currentButton

.removeClass("lock-open")

.addClass("lock");

else

currentButton

.removeClass("lock")

.addClass("lock-open");

 

break;

case 2: // Delete Button

$bar.accordion("removeGroupAt", groupIndex);

break;

}

}

});

});

});

 

// Bind the beforeselect event to prevent selection of groups when their close button is clicked

$bar

.off("beforeselect")

.on({

"beforeselect": function(e){

if (e.object.locked)

return false;

}

});

}

In order to bind the click event to our button elements, we will use a class selector. Based on button position in the toolbar, we can determine which button is clicked. In this way we can assign a different action for each button click. For example when Lock button is clicked a buttom image is also changed and the corresponding group becomes locked, that is unelectable.

By setting a value to the locked variable is not enough to prevent selection of groups. We also need to handle the beforeselect event, where depending on value of locked property we can determine whether a group will be selectable or not.

By default Accordion is empty with transparent background, and its appearance is only set by its contained groups. So if we remove all groups from the Accordion, an empty space will be shown. We need to make sure that when there are no groups, at least an framed block will appear. For this purpose we have handled the groupremoved event to track any changes to the group list, and when the list is empty we have changed the Accordion appearance by setting its background color and border.

// When group is removed rebind the events and update the appearance of Accordion

$bar.on("groupremoved", function(e){

rebindEvents();

updateAccordionAppearance();

});

 

// Call this method to update the appearance of Accordion

// When all groups are removed, show an empty Accordion

updateAccordionAppearance = function(){

var cssValue = {

"background-color": "transparent",

border: 0

}

 

if ($bar.accordion("getList").length === 0)

cssValue = {

"background-color": "white",

"border": "thin solid gray",

"border-radius": "3px"

}

 

$bar.css(cssValue);

}

All functionality explained in this article is demonstrated in above demo application. More information can be found in additional samples or Accordion widget online help pages.

Newsletter


Sign-up to our newsletter and you will receive news on upcoming events, latest articles, samples and special offers.
Name: Email: *
*By checking this box, I agree to receive a newsletter from Lidor Systems in accordance with the Privacy Policy. I understand that I can unsubscribe from these communications at any time by clicking on the unsubscribe link in all emails.