[Из песочницы] Аккордеон на AngularJS и Bootstrap

Аккордеон добавляет визуальное оформление и соответствующее поведение типа «горизонтальный аккордеон» произвольному (в рамках использованного шаблона и стилей) блоку разметки HTML.

Блок разметки должен иметь два обязательных элемента — общий контейнер и вкладки:

<ul ngc-accordion>
    <li ngc-accordion-tab="наименование1" template="template.html">... </li>
    <li ngc-accordion-tab="наименование2" template="template.html">... </li>
</ul>
    


Или так:

<div ngc-accordion>
    <div ngc-accordion-tab="наименование1" template="template.html">... </div>
    <div ngc-accordion-tab="наименование2" template="template.html">... </div>
</div>
    


Выглядит так:

b6b57d743302421885852ee0f08ee952.png
Живой пример тут. Реализован на двух AngularJS директивах ngc-accordion и ngc-accordion-tab.
К контейнеру вкладки ngc-accordion-tab применяется шаблон. К произвольному элементу шаблона подключается обработчик «кликов». К произвольному элементу шаблона применяется анимация изменения ширины.

Здесь рассматривается вариант применения аккордеона с шаблоном Bootstrap`ой структуры. Общая рамка вкладки рисуется классами «panel panel-default», внутри заголовок-кнопка «btn btn-default» и анимированный контейнер «accordion-tab-body», хранящий содержимое вкладки, обернутое парой контейнеров для рисования всяких «красивостей».

Вот пример шаблона для акордеона фиксированной высоты:

    <div class="accordion-tab-box panel panel-default" ng-class="{'panel-primary': t.opened, 'panel-default': !t.opened}">
        <div class="accordion-tab-header btn btn-default" style="padding-top: {{a.height - 30}}px;" ng-class="{'btn-primary': t.opened, 'btn-default': !t.opened}">
            <div class="accordion-tab-header-text"><strong>{{t.name}}</strong> {{a.index}}/{{t.index}}</div>
        </div>
        <div class="accordion-tab-body">
            <div style="width: {{t.bodyWidth}}px;">
                <div class="panel-body">
                    <div class="accordion-tab-scroll" style="overflow:auto; height: {{a.height-30}}px;" ng-transclude></div>
                </div>
            </div>
        </div>
    </div>
    


Обе директивы ngc-accordion и ngc-accordion-tab используют изолированный scope. В шаблоне вкладки доступны модели данных текущей вкладки t и всего аккордеона a.

Например, t.bodyWidth — ширина анимированного блока вкладки, используется для фиксации ширины содержимого для получения эффекта «выползания» одной вкладки из под другой.

Другое полезное свойство a.height — высота вкладки используется в этом шаблоне для правильного позиционирования подписи вкладки.

Текст наименования вкладки берется из атрибута ngc-accordion-tab, доступен в в свойстве модели данных t.name. Атрибут ngc-accordion тоже может иметь текстовое значение, оно доступно в свойстве модели данных a.name.

В шаблонах предназначенных для аккордеона с автовысотой НЕ СЛЕДУЕТ применять t.height внутри контейнера accordion-tab-body — это приведет к неправильному вычислению высоты аккордеона при изменении ширины окна браузера.

Разумеется шаблон может быть и любым другим, следует только не забывать пометить кликабельный элемент и анимированный элемент соответствующими классами accordion-tab-header и accordion-tab-body.

А вот код странички, аналогичной простому примеру:

    <!DOCTYPE HTML>
    <html lang="en" ng-controller="MainCtrl">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Accordion samples</title>
        <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet" />

        <link href="../accordion.css" rel="stylesheet" />
        <!--[if lt IE 9]><script src="../../assets/js/ie8-responsive-file-warning.js"></script><![endif]-->
        <script src="../bootstrap/js/ie-emulation-modes-warning.js"></script>

        <!--[if lt IE 9]>
        <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
        <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
        <![endif]-->

    </head>

    <body>

        <div class="container">

            <ul ngc-accordion="accordion0" style="height: 200px;">
                <li ngc-accordion-tab="tab1" ngc-template="../Templates/fixheight.html">tab1</li>
                <li ngc-accordion-tab="tab2" ngc-template="../Templates/fixheight.html">tab2</li>
                <li ngc-accordion-tab="tab3" ngc-template="../Templates/fixheight.html">tab3</li>
            </ul>

        </div>

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
        <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
        <!--<script src="../bootstrap/js/ie10-viewport-bug-workaround.js"></script>-->

        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
        <script src="../accordion.js"></script><!--http://js4lcaeq.github.io/v1/v1/-->
        <script src="app.js"></script>
    </body>
</html>

    


Кроме подключения Bootstrap и AngularJS, требуется файл стилей:

    .accordioncontainer {
    display: block;
    list-style: none;
    margin: 0;
    padding: 0;
    height: 100%;
    overflow: hidden;
    }

    .accordiontab {
    margin: 0;
    padding: 0;
    display: block;
    float: left;
    height: 100%;
    }

    .accordion-tab-box {
    height: 100%;
    margin-right: 2px;
    }

    .accordion-tab-body {
    float: left;
    overflow: hidden;
    }

    .accordion-tab-header {
    width: 30px;
    height: 100%;
    float: left;
    }

    .accordion-tab-header-text {
    transform: rotate(-90deg);
    }
    


И файл JavaScript:

    angular.module('app', ['AccordionModule'])
    .controller('MainCtrl', ['$scope',function ($scope) {

    }]);
    angular.bootstrap("html", ['app']);
    


Обязательные включения:

библиотека Bootstrap, стили - <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet" />
стили аккордеона - <link href="http://js4lcaeq.github.io/v1/v1/accordion.css" rel="stylesheet" />
библиотека jQuery - <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
библиотека Bootstrap, скрипты - <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
библиотека AngularJS - <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
скрипты аккордеона - <script src="http://js4lcaeq.github.io/v1/v1/accordion.js"></script>
запускающий скрипт - <script src="http://js4lcaeq.github.io/v1/v1/SimpleSample/app.js"></script>
    


Модель данных директивы ngc-accordion, доступна через атрибут ngc-model. В функциональном примере показано использование модели данных. Значение модели index проверяется и вы не сможете установить несуществующий индекс. Значение speed так же проходит простую проверку. Значение bussy устанавливается в true на время работы анимации.

© Habrahabr.ru