Angular

AngularJS Advanced Accordion

Angular JS

HTML Markup:

<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular-route.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular-resource.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular-cookies.min.js"></script>

<body ng-controller="ItemsCtrl" ng-cloak>
  <div class="loader" ng-hide="loadStatus === 'loaded'">Loading...</div>
  <div class="accordion-container" ng-show="loadStatus === 'loaded'">
    <label class="toggle-all-items"><input type="checkbox" ng-click="toggleAll()" ng-model="isAllToggled">{{toggleButtonText}} Items</label>
    <section class="count-{{accordionData.length}}">
      <article ng-repeat="item in accordionData" class="items-{{item.children.length}} self-id-{{item.id}}">
        <input type="checkbox" id="checkbox-{{item.id}}" ng-if="item.children.length > 1" ng-model="item.checked" ng-change="toggleOne()">
        <label for="checkbox-{{item.id}}">
          <span ng-if="item.children.length > 1">{{item.name}}</span>
          <a ng-if="item.children.length == 1" href="{{item.id}}/{{item.children[0].id}}">{{item.name}}</a>
        </label>

        <ul id="checkbox-{{item.id}}" ng-if="item.children.length > 1" >
          <li ng-repeat="child in item.children">
            <a href="{{item.id}}/{{child.id}}">{{child.name}}</a>
          </li>
        </ul>
      </article>
    </section>
  </div>
</body>

CSS

input[type='checkbox'] {
  display: none;
}
section {
  background-color: #F6FBFF;
  border: 1px solid #B8E0FF;
}
article {
  border-top: 1px solid #B8E0FF;
  border-bottom: 1px solid #fff;
}
article:first-child {
  border-top:0;
}
article label {
  display: block;
}
article label a,
article label span {
  display: block;
  padding: 0.8em 1em;
}
article ul {
  display: none;
}
article label:hover,
article input:checked ~ label {
  background-color: #B8E0FF;
}
article input:checked ~ label ~ ul {
  display: block;
}
.toggle-all-items {
  display: block;
  text-align: center;
  padding: 0.5em;
  background-color: #69A8D8;
  color: #fff;
  margin: 1em 5em;
  border-radius: 4px;
  cursor: pointer;
}
.toggle-all-items:hover {
  background-color: #417FAE;
}
.accordion-container {
  margin-bottom: 2em;
}

Javascript

angular
  .module("webdesigncolors", ['ngRoute','ngResource','ngCookies'])
  .controller('ItemsCtrl', function ($scope, $http, $cookies, $cookieStore) {
    var childrenArray = [];
    // Get id from cookie 'accordionItemID' for last active accordion item.
    var accordionItemID = parseInt($cookieStore.get('accordionItemID'));
    var isReturned = false;
    $scope.loadStatus = '';
    $scope.accordionData = [];

    $http
      .get('items.json')
      .error(function(data, status) {
        $scope.message = 'ERROR: Cannot fetch articles.';
      })
      .success(function(data, status) {
        // Set business item id in cookie 'accordionItemID' for last active accordion item.
        $scope.setitem = function (ele) {
          $cookieStore.put('accordionItemID', parseInt(ele.fragment.path));
        }
        data.forEach(function (d) {
          if (!d.hide) {
            // If cookie 'accordionItemID' matches with d.id, expand that accordion item.
            isReturned = accordionItemID === parseInt(d.id) ? true : false;
            $scope.accordionData.push({
              id: d.id,
              name: d.name,
              status: d.status,
              checked: (d.children.length > 1 ? isReturned : true),
              children: childrenArray 
            });
            d.children.forEach(function (cp) {
              if (cp.status === 'published') {
                childrenArray.push({
                  id: cp.id,
                  name: cp.name,
                  status: cp.status,
                  link: d.id + "/" + cp.id
                });
              }
            });
            childrenArray = [];
          }
        });
        $scope.loadStatus = 'loaded';
        // Remove cookie 'accordionItemID'.
        $cookieStore.remove('accordionItemID');

        // Accordion begins.
        $scope.toggleButtonText = "Show";
        $scope.toggleOne = function () {
          var checkboxStatus = [];
          $scope.accordionData.forEach(function (bp) {
            if (bp.children.length > 1) {
              checkboxStatus.push(bp.checked);
            }
          });

          if (checkboxStatus.indexOf(false) >= 0) {
            $scope.isAllToggled = false;
            $scope.toggleButtonText = "Show";
          } else {
            $scope.isAllToggled = true;
            $scope.toggleButtonText = "Hide";
          }
        };

        $scope.toggleAll = function () {
        $scope.accordionData.forEach(function (bp) {
          if (bp.children.length > 1) {
            bp.checked = $scope.isAllToggled;
          }
        });
        $scope.toggleButtonText = $scope.isAllToggled ? "Hide" : "Show";
      };
    });
});