2

I have a list of photographs being generated like the following snippet. Basically this would render a table like structure, with each photo being like a cell in this table. The ID of each photo like for example 1D means that the photo is in the first row of the table and in the 4th/D column.

<ul>
   <li class="row">
      <ul>
            <li class="photo" id="photo-1A">1A</li>
            <li class="photo" id="photo-1B">1B</li>
            <li class="photo" id="photo-1C">1C</li>
            <li class="photo" id="photo-1D">1D</li>
            <li class="photo" id="photo-2A">2A</li>
            <li class="photo" id="photo-2B">2B</li>
            <li class="photo" id="photo-2C">2C</li>
            <li class="photo" id="photo-2D">2D</li>
            <li class="photo" id="photo-3A">3A</li>
            <li class="photo" id="photo-3B">3B</li>
            <li class="photo" id="photo-3C">3C</li>
            <li class="photo" id="photo-3D">3D</li>
      </ul>
   </li>
</ul>

I have a JSON which includes whether the photo is available or not. Basically the JSON string is something along these lines:

[{"row":1,"position":"A","available":true},{"row":1,"position":"B","available":false},{"row":1,"position":"C","available":false},{"row":1,"position":"D","available":false},{"row":2,"position":"A","available":true},{"row":2,"position":"B","available":false},{"row":2,"position":"C","available":false},{"row":2,"position":"D","available":false},{"row":3,"position":"A","available":true},{"row":3,"position":"B","available":false},{"row":3,"position":"C","available":false},{"row":3,"position":"D","available":false}]

Now basically what I need to do is to parse this JSON string and when any of these photos have "available:true" in the JSON string, I add a class photo-available in the HTML. I am new to angular and I am not sure if there is an easy way to assign a class to the available photos. Would be glad if someone can tell me what to use or how to do it.

Edit: Angular Code is this:

<ul class="table-rows">
    <li class="photo-row" ng:repeat="photo in photos" ng:class="'photo-' + photo.row + photo.position">
        <ul class="table-photos">
            <li class="photo photo-available" ng:class="selectedOrNot(photo)" ng:init="photo.selected = false" ng:click="photo.selected = !photo.selected">

         <div class="photo-number">{{photo.row + photo.position}}</div>                          
        </li>                                   
     </ul>                                
  </li>
  <div class="clear"></div>                          

3
  • angular.fromJson(json) returns an object which you can then work with Commented Apr 6, 2014 at 17:18
  • @c0d3junk13 thanks for your reply. I managed to get the same by using JSON.parse(sessionStorage.seatBookings), however now I am completely stuck on how to go through each one of them and then when i find available=true, I assign the class photo-available to the corresponding <li> Commented Apr 6, 2014 at 17:28
  • whats stopping your from using "available" as the key and just reading the property value , it's an object after this , you can treat it as such ! Commented Apr 6, 2014 at 22:51

3 Answers 3

1

Update3
The reason you are unable to restore previous selections is that you are overwriting the photo's selected property with ng-init:

ng:init="photo.selected = false"
ng-class="{'selected': photo.selected, 'available': photo.available}"

When you combine these two, the 'selected' class will never be added because photo.selected has been hardcoded to false. You just need to remove ng-init, and the previous selection will trigger ng-class to add the correct class.

Here is a working demo: http://plnkr.co/tVdhRilaFfcn55h6mogu

Original answer
If the list of photos is not the same array as the list of available photos, you can use a directive to add the class.

app.directive('availablePhoto', function($filter) {
  return {
    restrict: 'A',
    scope: true,
    link: function(scope, element, attr) {
      var id = attr.id

      var regex = /photo-(.)(.)/g;
      var match = regex.exec(id);

      var row = match[1]
      var position = match[2]

      var photo = $filter('filter')(scope.photos, {row:row, position:position}, false)

      console.log(photo);

      if (photo[0].available) {
        element.addClass('available');
      }
    }
  }
});

Then attach it to each list item like this:

<li class="photo" id="photo-1A" available-photo>1A</li>

Here is a demo: http://plnkr.co/WJCmLf2M39fcUnvOPyNA

Update1

Based on your update, I see that there is just one array populating the list, and it contains the available flag. Therefore, you don't need a custom directive - ngClass will work. Here it is integrated into your code sample:

<ul class="table-rows">
  <li class="photo-row" ng:repeat="photo in photos" ng:class="'photo-' + photo.row + photo.position">
    <ul class="table-photos">
      <li class="photo" ng-class="{'available': photo.available}" ng:init="photo.selected = false" ng:click="photo.selected = !photo.selected">
        <div class="photo-number">{{photo.row + photo.position}}
        </div>                          
      </li>                                   
    </ul>
  </li>
  <div class="clear"></div>  
</ul>

I have update the plunker to demonstrate this.
http://plnkr.co/WJCmLf2M39fcUnvOPyNA

Update2
Since you need ngClass to add multiple classes, use it like this:

ng-class="{'selected': photo.selected, 'available': photo.available}"

Demonstration of selected + available: http://plnkr.co/WJCmLf2M39fcUnvOPyNA

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

9 Comments

I have updated my question and included the code generating the <ul> structure. Somehow when I am using your app.directive it is not working for some reason. What I am not understanding is how from having "available-photo" in the <li> basically does the trick. Also, I am not sure what your regex and code actually does. Would be extremely glad if you can give me a quick explanation
Based on your update, my code isn't necessary because there are not two arrays. I will update in a few minutes.
just to have a better idea, I have uploaded my code here: www.designsconcept.com/cinema so you get a better idea of the actual scenario. The question here is just for a related scenario
basically I still need the ng-class I have. Is it possible to add to it, and have something like: ng:class="selectedOrNot(photo); {'available': photo.available}"? (you can see the thing working here: www.designsconcept.com/cinema . Basically the selectedOrNot puts the highlight state when the user clicks on the seat)
@user1809790, i wasn't able to open your goo.gl link, but i think i understand that you are trying to apply two classes conditionally using ngClass. please see updated answer.
|
0

Here's a plnkr with an example of how to solve your problem. You need to make use of both the ng-repeat and the ng-class:

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

As you can see, I also added some filters for your photos, they will come handy if you need to just show the available ones (for some reason).

Here's the documentation for angular $filter service

2 Comments

I have added my AngularJS which is generating the <ul> structure. FOr some reason when I am adding your code it is not working :( Not sure what I am doing wrong
just to have a better idea, I have uploaded my code here: www.designsconcept.com/cinema so you get a better idea of the actual scenario. The question here is just for a related scenario
0

I think this meets all your requirements:

$scope.photos = JSON.parse('[{"row":1,"position":"A","available":true},{"row":1,"position":"B","available":false},{"row":1,"position":"C","available":false},{"row":1,"position":"D","available":false},{"row":2,"position":"A","available":true},{"row":2,"position":"B","available":false},{"row":2,"position":"C","available":false},{"row":2,"position":"D","available":false},{"row":3,"position":"A","available":true},{"row":3,"position":"B","available":false},{"row":3,"position":"C","available":false},{"row":3,"position":"D","available":false}]');

and then you can just use ng-repeat to build the list:

<ul>
   <li class="row">
      <ul>
        <li ng-repeat="photo in photos" class="photo" ng-class="{'photo-available': photo.available}" id="photo-{{photo.row}}{{photo.position}}">{{photo.row}}{{photo.position}}</li>
      </ul>
   </li>
</ul>

So what we are doing is we are taking our photo array, and for every one (ng-repeat="photo in photos") we are assigning that specific item to the variable photo. Then, if photo.available is true, we assign the class photo-available (ng-class="{'photo-available': photo.available}").

Then, we can simply interpolate the id and text based off the properties row and position ({{photo.row}}{{photo.position}}). You could also have done that like this {{photo.row + photo.position}} but that could cause issues if they were both numbers.

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

8 Comments

So... you copied and pasted some code from my Plnkr? I see you have the same filter I added to my answer but you are not using it... Not cool man.
Yeah I wanted a Plnkr with angular set up, it's not like I stole your answer.
You took my answer and trimmed some extra filters I added in case he needed them.
No, you deleted your post, modified your plnkr, and then undeleted your post. Yours didn't have ng-class at all when I did mine
In fact, plnkr lets you see revisions, so go ahead and click on either of the first two versions. Kind of looks like you actually copied from mine
|

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.