AngularJS - parse JSON

18,857

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

Share:
18,857
user1809790
Author by

user1809790

Updated on June 04, 2022

Comments

  • user1809790
    user1809790 almost 2 years

    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>                          
    

  • GonchuB
    GonchuB about 10 years
    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.
  • dave
    dave about 10 years
    Yeah I wanted a Plnkr with angular set up, it's not like I stole your answer.
  • GonchuB
    GonchuB about 10 years
    You took my answer and trimmed some extra filters I added in case he needed them.
  • dave
    dave about 10 years
    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
  • dave
    dave about 10 years
    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
  • GonchuB
    GonchuB about 10 years
    You took mine, edited and forked it while I was working on it. That's what the versions say. But as you say. Later.
  • user1809790
    user1809790 about 10 years
    @dave I am using an ng-repeat as above. This gives you an idea how the <ul> structure is being generated. Can you tell me where I need to put the ng-class="{'photo-available':photo.available}" as somehow it is not working for me :(
  • user1809790
    user1809790 about 10 years
    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
  • user1809790
    user1809790 about 10 years
    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
  • j.wittwer
    j.wittwer about 10 years
    Based on your update, my code isn't necessary because there are not two arrays. I will update in a few minutes.
  • Benjamin Gruenbaum
    Benjamin Gruenbaum about 10 years
    @GonchuB using a derivative of part of your work is perfectly acceptable in Stack Overflow, the missing bit is attribution.
  • user1809790
    user1809790 about 10 years
    just to have a better idea, I have uploaded my code here: goo.gl/MZK0Nb so you get a better idea of the actual scenario. The question here is just for a related scenario
  • user1809790
    user1809790 about 10 years
    just to have a better idea, I have uploaded my code here: goo.gl/MZK0Nb so you get a better idea of the actual scenario. The question here is just for a related scenario
  • user1809790
    user1809790 about 10 years
    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: goo.gl/MZK0Nb . Basically the selectedOrNot puts the highlight state when the user clicks on the seat)
  • j.wittwer
    j.wittwer about 10 years
    @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.
  • user1809790
    user1809790 about 10 years
    @j.witter this is something very close to what I need to obtain, but still it didnt work in my code :( I have re-uploaded it and is available from goo.gl/MZK0Nb .Basically what I need to do is the first time you enter and select the seats you get the highlighted/selected state. But if you send the booking, and go back to the homepage for example and go back to the same film page, and the date and time of the show match, you should see the seats you have booked previously grayed-out, which is done by adding the class seat-booked
  • user1809790
    user1809790 about 10 years
    this is just a dummy application to try Angular and therefore once you submit your "booking" I am actually saving in the local session (local storage) and when you try to access the same page again, I try to grab the JSON from your local session and then set the seats you had booked previously to booked so you wouldnt be able to re-book them
  • j.wittwer
    j.wittwer about 10 years
    OK, so it really is more like my first answer. You have two arrays. One to populate the options, and one that holds previous selection.
  • j.wittwer
    j.wittwer about 10 years
    @user1809790, figured it out. see final updated answer.