Reputation: 251
I am trying to create an image gallery using angular ui and bootstrap. The image gallery has 4x4 rows of photos and I want the user to be able to open the photo in a modal window when he clicks on the photo. The modal window should display the photo in a carousal so he can see the entire image gallery by "next" and "prev"
Below is my code. The modal window opens up but does not contain the carousel.
<div id="listing-detail-gallery" class="container">
<ul class="row">
<li class="col-lg-2 col-md-2 col-sm-3 col-xs-4" ng-repeat="image in selectedListing.images">
<img class="img-responsive" ng-click="openModal()" src="assets/images/{{image}}"/>
</li>
</ul>
</div>
controller( 'ListingDetailsCtrl', function ListingDetailsCtrl($scope ,$modal, $stateParams,ListingService,CategoryService) {
$scope.id= $stateParams.id;
$scope.selectedListing = ListingService.find($scope.id);
$scope.category= CategoryService.findByCode($scope.selectedListing.category);
//Open Modal Window for image
$scope.openModal = function () {
var modalInstance = $modal.open({
animation: true,
size:"lg",
template: '<div class="modal-body"><carousel><slide ng-repeat="image in items">{{image}} <img style="margin:auto;" ng-src="assets/images/{{image}}"></slide></carousel></div>',
resolve: {
items: function () {
return $scope.selectedListing.images;
}
}
});
};
please help me if you can figure out what is wrong here.
Upvotes: 2
Views: 5505
Reputation: 17372
Here's a demo (It's based off on an older demo I had so it has a slightly different template and some CSS added to make it pretty, but it's the same code described below):
I would refactor your controller so that you don't have to use a separate controller for your modalInstance. That will make it much easier:
controller( 'ListingDetailsCtrl', function ListingDetailsCtrl($scope, $modal, $stateParams,ListingService,CategoryService) {
$scope.id= $stateParams.id;
$scope.selectedListing = ListingService.find($scope.id);
$scope.category= CategoryService.findByCode($scope.selectedListing.category);
$scope.openModal = function(indx) {
//This will let you open the carousel to the image that was clicked
$scope.selectedListing.images[indx].active=true;
$scope.modalInstance= $modal.open({
animation: true,
size:"lg",
//To set the active slide when loading the carousel, just add
//active = "image.active" to the slide element. Also, we're using
//the current scope, so change your slide repeat to "image in
//selectedListing.images"
template: '<div class="modal-body"><carousel><slide ng-repeat="image in selectedListing.images" active="image.active">{{image}}<img style="margin:auto;" ng-src="assets/images/{{image}}"></slide></carousel></div>',
});
};
$scope.ok = function () {
$scope.modalInstance.close();
};
});
Then you just need to make one change to your HTML view so that you are passing the index of the image to the openModal fn:
<div id="listing-detail-gallery" class="container">
<ul class="row">
<li class="col-lg-2 col-md-2 col-sm-3 col-xs-4" ng-repeat="image in selectedListing.images">
<img class="img-responsive" ng-click="openModal($index)" src="assets/images/{{image}}"/>
</li>
</ul>
</div>
P.S. You'll notice that I hid the carousel indicators in the carousel. There's a really ugly unresolved bug in ui-bootstrap 0.13.0 that causes the indicators to be ordered incorrectly if you have a lot of slides. There are two simple options to fix this if you want to use the indicators. One is modify the carousel.html template and remove orderBy:'index'
from the indicators. Or, two use the 0.12.x version until fixed. (I'd go for the former).
Upvotes: 2
Reputation: 21147
Rather than reinvent the wheel (although it can be a good learning experience sometimes) I would suggest you use an existing angular module. I recently used this one in a project and it contains all the features that you're looking for: angular bootstrap lightbox. The basic example will get you up and running with the functionality you're after.
<ul ng-controller="GalleryCtrl">
<li ng-repeat="image in images">
<a ng-click="openLightboxModal($index)">
<img ng-src="{{image.thumbUrl}}" class="img-thumbnail">
</a>
</li>
</ul>
angular.module('app').controller('GalleryCtrl', function ($scope, Lightbox) {
$scope.images = [
{
'url': '1.jpg',
'caption': 'Optional caption',
'thumbUrl': 'thumb1.jpg' // used only for this example
},
{
'url': '2.gif',
'thumbUrl': 'thumb2.jpg'
},
{
'url': '3.png',
'thumbUrl': 'thumb3.png'
}
];
$scope.openLightboxModal = function (index) {
Lightbox.openModal($scope.images, index);
};
});
Upvotes: 1