Аккордеон добавляет визуальное оформление и соответствующее поведение типа «горизонтальный аккордеон» произвольному (в рамках использованного шаблона и стилей) блоку разметки 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>
    

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



Живой пример тут. Реализован на двух 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 на время работы анимации.

Комментарии (8)


  1. Evgeny42
    23.09.2015 15:58
    +7

    Аккордеон в 2015


    1. Androvas
      23.09.2015 16:49

      Сейчас делаю селект с множественным выбором на той же платформе Angular + Bootstrap. Удобен для выбора пары десятков записей из миллиона. Автоподсказка и прокрутка совсем не тормозит но миллион записей это пара мегабайт и их как то надо получить на клиенте, так что вероятно миллион это разумный предел.


  1. k0sh
    23.09.2015 17:09

    А чем родной не подошел?


    1. Androvas
      23.09.2015 17:13
      +1

      горизонтальный был нужен


  1. ArtKom
    23.09.2015 17:16
    -1

    Хотелось бы поинтересоваться у автора, а чем описанный метод лучше того который предлагается в Бутстрапе? Особенно учитывая тот факт, что сам Бутстрап вы используете в примере.

    Имхо, получается ситуация когда берем молоток для того чтобы с его помощь сделать молоток… Может есть какие-то иные плюсы в описанном методе, оправдывающие такое использование?


    1. Androvas
      23.09.2015 17:38

      Бутстрапный аккордеон вертикальный, а был нужен горизонтальный и к тому же в проекте используется ангуляр. Разумно воспользоваться теми инструментами которые уже всключены в проект. В общем, конечно можно всю работу сделать на чистом JS и даже без jQuery, но кто же откажется от таких вкусняшек и за бесплатно.


  1. rogrom
    23.09.2015 20:38

    в bower/npm бы залить


    1. Androvas
      24.09.2015 09:31

      Да, верно, пожалуй многовато подключений автоматизация процесса могла бы подсластить жизнь