1

I have an image gallery in angular js which multiple images. When a user clicks an image I want to add a style (in this case a border). If the clicks one of the selected images again, i want to remove the border. I have it working to add/remove imageURLs to an array of "selected_images" on click but I can't get the styles to add/remove.

Here is my markup:

    <div class="col-md-3 col-sm-4 col-xs-6" ng-repeat="imageURL in property.imageURLs">
        <img src={{imageURL}} ng-click="select_image(imageURL)" class="img-responsive" ng-class="{ 'selected-image': image_is_selected(image) }" style="max-height: 120px;" alt="" title="">
</div>

And the js:

$scope.image_is_selected = function(image) {
        if($scope.selected_images.indexOf(image) == -1) {
            return false;
        } else {
            return true;
        }
    }

    $scope.select_image = function(image) {
        console.log('image: ' + image);
        var image_index = $scope.selected_images.indexOf(image)
        console.log('image index: ' + image_index);
        if(image_index != -1) {
            $scope.selected_images.splice(image_index, 1);
        } else {
            $scope.selected_images.push(image);
        }
    }

This obviously isn't working as image_is_selected gets called a bunch of times... What is the best practice here?

5 Answers 5

2

You can simplify things by toggling a property on each image using ng-click:

<div class="col-md-3 col-sm-4 col-xs-6" ng-repeat="image in property.images">
  <img src={{image.URL}} 
  ng-click="image.selected = !image.selected"  
  ...

Then ng-class is simply:

  ng-class="{ 'selected-image': image.selected }" 

If you want to try the code for yourself, here it is on Plunkr.


To keep your existing data structure, you could populate an object on the fly with the selected property of each image:

<div class="col-md-3 col-sm-4 col-xs-6" ng-repeat="image in property.imageURLs">
  <img src={{image}} 
  ng-click="selected_images[image] = {selected: !selected_images[image].selected }"
  ng-class="{ 'selected-image': selected_images[image].selected }" 

But this requires creating the selected_images ahead of time:

$scope.selected_images = {};

http://plnkr.co/edit/O3MUv0aT81O1PaEnRbQv?p=preview

Sign up to request clarification or add additional context in comments.

5 Comments

but i also want to add the image url to an array, can this be accomplished with this strategy?
with this approach the original array is augmented with information about which images are selected. at any moment, you can loop through the array and push images that are selected into another array. i prefer doing this work on demand instead of with each selection.
it isn't image.URL, it's imageURL... it's just a string, not an object.
I ended up doing this: ng-click="image.selected = !image.selected; select_image(imageURL);"
glad you got it working. i did update with an alternative for your imageURLs array.
2

Try this it me be help you

ng-click on Image add class and again click on image remove class

Here is Html file

 <html ng-app="plunker">
     <head>
        <meta charset="utf-8" />
        <title>AngularJS Plunker</title>
           <link rel="stylesheet" href="style.css" />
           <script data-require="[email protected]" src="https://code.angularjs.org/1.2.16/angular.js" data-semver="1.2.16"></script>
           <script src="script.js"></script>
     </head>
<body ng-controller="MainCtrl">
    <div ng-repeat="image in images">
       <img src={{image.img}} ng-click="selectImage($index)" ng-class="{ 'selected-image': $index === selectIdx }" >
    </div>
</body>
</html>

Here is Controller

 var app = angular.module('plunker', []);
 app.controller('MainCtrl', function($scope) {
    $scope.images = [
        {img: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSHIwFa7lBRjCtY5K2WLGRuJ5XcXOwTUdgPPE1JKJHWEaoaG0Yh'},
        {img: 'https://encrypted-tbn1.gstatic.com/images?q=tbn:ANd9GcTOAn_TGFgVS9CIW0y1hJ3deENr6KJx0AWP6W8FPvNDRcO-K5MyXg'},
        {img: 'https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcR0In9KzRbpbnrVC5U1URXjHuQoTVhDjuemydVBzgJbPogvqaHa'}
    ]

 $scope.selectIdx = -1;
 $scope.selectImage = function ( $index ) {
  if($scope.selectIdx === $index) {
     $scope.selectIdx = -1;
   } else {
      $scope.selectIdx = $index;
   }
  }
});

Here is Css File

 .selected-image {
 border: 5px solid black; 
 }

Plunker Link http://plnkr.co/edit/tm3rpkiKMBxhX98yr0IX?p=preview

Comments

0

There are many ways of achieving your required outcome. I'll try to explain one of them which I think would be best suited for your requirements. Keep in mind that when using ng-repeat you already have a reference to "$index" and that you can pass it direct into whatever expression you might have inside ng-click. Here's an solution:

HTML:

<div class="col-md-3 col-sm-4 col-xs-6" 
     ng-repeat="imageURL in property.imageURLs">
    <img src={{imageURL}} 
      ng-click="select_image($index)" 
      class="img-responsive" 
      ng-class="{ 'selected-image': $index === selectedImageIndex }" 
      style="max-height: 120px;" alt="" title="">
</div>

Code:

$scope.selectedImageIndex = -1;
$scope.select_image = function ( $index ) {
    $scope.selectedImageIndex = $index;
}

1 Comment

I think the OP's intention is to select multiple images, with your code above, it does not accomplish such requirement.
0

If you don't want to change the structure of your property.imageURLs variable into an array of objects then I think it would be better to create another variable $scope.selected = [] to store the boolean value to determine the selection of each image by index.

Example

HTML

<div class="gallery">
  <img ng-repeat="url in imageUrls track by $index" ng-src="{{url}}" ng-class="{'selected-image': selected[$index]}" ng-click="selected[$index] = !selected[$index]" />
</div>

JAVASCRIPT

$scope.selected = []

And if you're ready to save these selected items and store them in an array, you can append this in your controller

JAVASCRIPT

  $scope.save = function() {
    var selectedImages = []

    angular.forEach($scope.selected, function(isSelected, index) {
      if(isSelected)
        selectedImages.push($scope.imageUrls[index])
    })

    // Save your images
    console.log(selectedImages)
  }

See the associated plunker of the example above.

Note: As you can see that I've used the track by $index ng-repeat, this is to ensure that even if there are multiple images with the same urls, it does not throw a duplication error.

Comments

0

Try this

<div class="col-md-3 col-sm-4 col-xs-6" ng-repeat="imageURL in property.imageURLs">
        <img src={{imageURL}} ng-click="select_image(imageURL)" class="img-responsive" ng-class="{active: isActive(imageURL)}" style="max-height: 120px;" alt="" title="">
</div>

Now in your controller

$scope.select= function(item) {
        $scope.selected = item; 
 };

 $scope.isActive = function(item) {
        return $scope.selected === item;
 };

.active class will be added to the selected image .

You can add styles to active class

More Info

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.