I am trying to implement Bootstrap Carousel with custom indicator using Angular, Carousel works well, but I am not able customize indicator.
var App = angular.module('App', ['ngAnimate', 'ui.bootstrap', 'ngTouch']);
App.controller('Carousel', function($scope, $http, $element){
$scope.myInterval = 5000;
$scope.noWrapSlides = false;
var slides = $scope.slides = [];
$scope.slides = [{"img":"images\/bg-slider1.jpg","name":"GIFTS","class":"pinkbg"},{"img":"images\/bg-slider2.jpg","name":"FASHION","class":"ltgreen"},{"img":"images\/bg-slider1.jpg","name":"ASTROLOGY","class":"voilet"},{"img":"images\/bg-slider2.jpg","name":"ORGANIC","class":"green"},{"img":"images\/bg-slider1.jpg","name":"SPORTS","class":"yellow"},{"img":"images\/bg-slider2.jpg","name":"APPLIANCES","class":"grey"}];
$scope.getNameByIndex = function(index){
return $scope.slides[index]['name'];
}
});
angular.module("template/carousel/carousel.html", []).run(["$templateCache", "$http", function($templateCache, $http) {
$templateCache.put("template/carousel/carousel.html",
"<div ng-mouseenter=\"pause()\" ng-mouseleave=\"play()\" class=\"carousel\" ng-swipe-right=\"prev()\" ng-swipe-left=\"next()\">\n" +
" <ol class=\"carousel-indicators\" ng-show=\"slides.length > 1\">\n" +
" <li ng-repeat=\"slide in slides | orderBy:indexOfSlide track by $index\" ng-class=\"{active: isActive(slide)}\" ng-click=\"select(slide)\" class='{{slide.class}}'>{{slide.name}}</li>\n" +
" </ol>\n" +
" <div class=\"carousel-inner\" ng-transclude></div>\n" +
"</div>\n" +
"");
}]);
$scope.slides
has additional attributes, name
and class
that needs to placed in indicator. how can I do that ?
See Plunker
To start off this caught my interest why the scope was not accessible. After a detailed analysis of the source code available on GitHub i found that the scope is being isolated in the library.
Plukr Link
On plunkr i have modified the library. File name : angular-bootstrap-modified.js
Read below for details.
See the below code chunk from Git Hub:
.directive('carousel', [function() {
return {
restrict: 'EA',
transclude: true,
replace: true,
controller: 'CarouselController',
controllerAs: 'carousel',
require: 'carousel',
templateUrl: function(element, attrs) {
return attrs.templateUrl || 'template/carousel/carousel.html';
},
scope: {
interval: '=',
noTransition: '=',
noPause: '=',
noWrap: '&'
}
};
}])
Newly created isolated scope variable for the directive inherits below data from its parent scope.
{
interval: '=',
noTransition: '=',
noPause: '=',
noWrap: '&'
}
Finally found that its a limitation from the library itself.
So i modified the library to achieve the solution. Below is what i changed
Library code:
scope: {
interval: '=',
noTransition: '=',
noPause: '=',
noWrap: '&',
slidesData : '=slides'
}
and in HTML:
<carousel interval="myInterval" no-wrap="noWrapSlides" slides="slides">
After the modification, volla! now the directive isolated scope inherits the slides data too. Sweet!
Info on Angular directives can be found - here
Next tweaked the template code: All i did was change the slides reference to slideData
angular.module("template/carousel/carousel.html", []).run(["$templateCache", "$http", function($templateCache, $http) {
$templateCache.put("template/carousel/carousel.html",
"<div ng-mouseenter=\"pause()\" ng-mouseleave=\"play()\" class=\"carousel\" ng-swipe-right=\"prev()\" ng-swipe-left=\"next()\">\n" +
" <ol class=\"carousel-indicators\" ng-show=\"slidesData.length > 1\">\n" +
" <li ng-repeat=\"slide in slidesData | orderBy:indexOfSlide track by $index\" ng-class=\"{active: isActive(slide)}\" ng-click=\"select(slide)\" class='{{slide.class}}'>{{slide.name}} - {{$index}}</li>\n" +
" </ol>\n" +
" <div class=\"carousel-inner\" ng-transclude></div>\n" +
"</div>\n" +
"");
}]);
Good now i can see the the name and class on <ol></ol>
tag element rendered.
But now the switching animation doesnt happen on <li>
.Below is the routine that compares the scope instead of index(i donno why?)
$scope.isActive = function(slide) {
return self.currentSlide === slide;
};
I figured out by watching the expressions on my debugger console
If you want to achieve it somehow.. You have to modify the library source itself. I would advice you to check out other sliders if you want customized sliders or use as is provided by the Angular Bootstrap library.
Also GitHub issue logged
Carousel customization will be implemented in the future versions as per the Github issue update