Bare minimum code for AngularJS Carousel

paultamalunas picture paultamalunas · Jan 18, 2016 · Viewed 21.7k times · Source

I spent all day trying to get the "example" AngularJS Carousel to work, and it was only thanks to finally stumbling upon this topic that I finally got it to work.

Starting with the Carousel example from the AngularJS Bootstrap page, there are some great HTML and JS snippets, but it's impossible to tell by looking at the site, which and how many JS and CSS files are needed to make the carousel work. I've tried everything to make it work, I ended up with all kinds of extraneous (I think?) JS and CSS files being included.

Even their concept of angular.module('ui.bootstrap.demo').controller... I found to be confusing, because I was not able to get the app to work until I tried angular.module('myApp', ['ui.bootstrap', 'ui.bootstrap.tpls', 'ngAnimate', 'ngTouch']) -- and even then I'm not sure how many of these modules are required.

Can someone please list the minimum JS and CSS files required to make the Carousel perform properly, and a brief reason why? And is there some defined 'ui.bootstrap.demo' that I missed, that would have simplified things a bit? Thanks.

Answer

pixelbits picture pixelbits · Jan 18, 2016

You can check out the bare minimum bootstrap carousel from the latest bootstrap site: http://getbootstrap.com/javascript/#carousel

The next step is getting this into a bare minimum AngularJS directive, which as it turns out is really simple.

Links

Since Bootstrap requires jQuery for the carousel component, you'll need the latest version of jQuery: https://code.jquery.com/jquery-2.1.4.js.

Also add the necessary links from Bootstrap: http://getbootstrap.com/getting-started/#download

Carousel Directive

app.directive('carousel', function($timeout) {
   return {
      restrict: 'E',
      scope: {
        links: '=' 
      },
      templateUrl: 'carousel.html',
      link: function(scope, element) {
        $timeout(function() {
          $('.carousel-indicators li',element).first().addClass('active');
          $('.carousel-inner .item',element).first().addClass('active');
        });
      }
   }
});

According to Bootstrap's documentation:

Initial active element required

The .active class needs to be added to one of the slides. Otherwise, the carousel will not be visible.

In order to add the .active class after rendering, we use $timeout within the link function.

Carousel.html

This is basically a copy of the HTML provided by Bootstrap which has been modified with ngRepeat and ngSrc to make it dynamic:

<div id="carousel-example-generic" class="carousel slide" data-ride="carousel">
  <!-- Indicators -->
  <ol class="carousel-indicators">
    <li ng-repeat="link in links" data-target="#carousel-example-generic" data-slide-to="{{$index}}"></li>
  </ol>

  <!-- Wrapper for slides -->
  <div class="carousel-inner" role="listbox">
    <div class="item" ng-repeat="link in links">
      <img ng-src="{{link.src}}" alt="{{link.src}}">
      <div class="carousel-caption">
       {{link.caption}}
      </div>
    </div>
  </div>

  <!-- Controls -->
  <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
    <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
    <span class="sr-only">Previous</span>
  </a>
  <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
    <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
    <span class="sr-only">Next</span>
  </a>
</div>

Usage

To use the directive, initialize a list of links in a controller:

app.controller('ctrl', function($scope) {
   $scope.links =[
     { src:"http://www.conceptcarz.com/images/Suzuki/suzuki-concept-kizashi-3-2008-01-800.jpg", alt:"", caption:""},
     { src:"http://www.conceptcarz.com/images/Volvo/2009_Volvo_S60_Concept-Image-01-800.jpg", alt:"", caption:""},
     { src:"http://www.sleepzone.ie/uploads/images/PanelImages800x400/TheBurren/General/sleepzone_hostels_burren_800x400_14.jpg", alt:"", caption:""},
  ];
});

Add the directive to your view and pass in the links model that you defined in your controller earlier:

<body ng-controller="ctrl">
  <div style="width:800px; height: 400px">
    <carousel links="links"></carousel>
  </div>
</body>

Note: The inline style is necessary to ensure that the image size takes up the entire canvas. There may be better ways to do this - consult Bootstrap.

Demo Plnkr