LIDOR SYSTEMS

Advanced User Interface Controls and Components

Custom Accordion Header with Buttons in AngularJS

Created: 07 December 2015

Usually header in Accordion directive displays only a title. By modifying the HTML of accordion header, you can add custom content and arrange it in custom layout. In this example, we will show you how to add buttons to each header in accordion directive and each button will start a different action when clicked.

The following sections of this article will show you how to create and add groups to accordion directive from code, using several different methods and events.

{{group.text}}
{{group.name}} Content
Accordion directive is part of IntegralUI Studio for Web
a suite of UI Components for development of web apps

In our demo, each accordion header along with its title also displays three buttons. Whenever a header button is clicked, a different action is executed (see more below).

Similar: How to Create Custom Header for Angular Accordion 2

Accordion Header with Buttons

To create a header with custom content, we will use the IntegralUI Accordion Header directive. This directive allows us to override the default appearance and behavior of accordion header with our own.

In our case, we will set accordion header to contain a title and three buttons. For title, we are using the element, and for buttons a <div> element enclosing a <span> element. Here how this looks like:

angular

.module("appModule", ["integralui"])

.controller("appCtrl", ["$scope", "IntegralUIAccordionService", "$timeout", function($scope, $ctrlService, $timeout){

// A unique identifer for the Accordion

$scope.ctrlName = "ctrlSample";

 

// An object that holds all accordion groups

$scope.groups = [

{ id: 1, name: 'Group1', text: 'Header 1', locked: false },

{ id: 2, name: 'Group2', text: 'Header 2', locked: false },

{ id: 3, name: 'Group3', text: 'Header 3', locked: false }

];

}]);

<!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/angular.min.js"></script>

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

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

</head>

<body>

<div ng-app="appModule" ng-controller="appCtrl">

<iui-accordion name="{{ctrlName}}" class="directive" groups="groups" before-select="onBeforeSelect(e)">

<iui-accordion-group ng-repeat="group in groups" name="{{group.name}}">

<iui-accordion-header>

<span class="header-title">{{group.text}}</span>

<div class="toolbar" ng-mousedown="$event.stopPropagation();">

<div class="header-button"><span class='icons recycle' ng-click="onRecycle(group)"></span></div>

<div class="header-button"><span class='icons' ng-class="group.locked == false ? 'lock-open' : 'lock'" ng-click="onLock(group)"></span></div>

<div class="header-button"><span class='icons delete' ng-click="onDelete(group)"></span></div>

</div>

</iui-accordion-header>

<div class="group-content">

{{group.name}} Content

</div>

</iui-accordion-group>

</iui-accordion>

</div>

</body>

</html>

.iui-accordion-group-header

{

font-size: 1.2em;

}

.iui-accordion-group-header-selected

{

color: #c60d0d;

font-weight: bold;

}

.header-title

{

display: inline-block;

padding-top: 3px;

vertical-align: middle;

}

.group-content

{

padding: 25% 10px;

text-align: center;

}

.icons

{

background-image: url(header-icons.png);

border: thin solid transparent;

display: block;

}

.delete

{

background-position: -17px 0;

}

.lock

{

background-position: -34px 0;

}

.lock-open

{

background-position: -54px 0;

}

.recycle

{

background-position: -72px 0;

}

.toolbar

{

margin: 0;

padding: 0;

float: right;

}

.header-button

{

display: inline-block;

border: thin solid transparent;

margin: 0;

padding: 2px 2px 3px 2px;

}

.header-button:hover

{

background-color: white;

border-color: #969696;

}

The background of the span element is painted using an image that represents our button. Then this element is enclosed within the block element (div), so that when it is hovered a frame around the image is shown. You can look out more about this in CSS styles above.

Custom Action on Header Button Click

The next step is to add functionality to header buttons so that whenever they are clicked, some action is executed.

In our case, we have three buttons:

  • recycle - shows a popup message
  • lock - locks the corresponding group and prevents it from expanding
  • delete - removes the corresponding group from the Accordion

The first action is simple; whenever the recycle button is clicked, a popup window is shown with a message of accordion group to which the button belongs.

$scope.onRecycle = function(group){

alert("Recycle button clicked for: " + group.text);

}

In the second action, the corresponding group is locked, meaning it cannot expand its content. This will remain until the group is unlocked by clicking again on the lock button.

Note If the group is already expanded, a search for the next visible group is executed, so that we always have one group expanded.

// Gets the currently selected group in the accordion

var getCurrentSelection = function(){

return $ctrlService.selectedGroup($scope.ctrlName);

}

 

// Retrieves the next group that is not locked

var getNextGroup = function(group){

var foundGroup = null;

 

var index = $scope.groups.indexOf(group);

or (var i = index+1; i < $scope.groups.length; i++){

if ($scope.groups[i].locked == false){

foundGroup = $scope.groups[i];

break;

}

}

 

if (!foundGroup){

for (var i = index-1; i >= 0; i--){

if ($scope.groups[i].locked == false){

foundGroup = $scope.groups[i];

break;

}

}

}

 

return foundGroup;

}

 

// When lock button is clicked, collapse the corresponding group and lock it

$scope.onLock = function(group){

group.locked = !group.locked;

 

if (group.locked && group == getCurrentSelection()){

var nextGroup = getNextGroup(group);

$ctrlService.selectedGroup($scope.ctrlName, nextGroup);

}

}

 

// If the group is locked, cancel the selection

$scope.onBeforeSelect = function(e){

if (e.group.locked)

return false;

}

In last action, the corresponding group is removed from the accordion.

$scope.onDelete = function(group){

$ctrlService.removeGroup($scope.ctrlName, group);

}

Conclusion

There are cases when we want to create accordions with custom header performing some action using buttons. IntegralUI Accordion directive for AngularJS allow us to meet this requirement, providing a feature to customize the appearance and behavior of accordions.

In our demo, we have created an accordion which header has three buttons that when clicked executes a custom action. Regarding your application requirements, you can further enhance the behavior of accordions, using this sample as a guideline.

Did you Like this Article?


Enter your e-mail address below and you will receive latest articles as well as news on upcoming events and special offers.