Unveiling the Power of AngularJS for Parsing JSON Data

A list of images is being generated in a table-like structure using the code snippet below. Each image represents a cell in this table, with its ID specifying its row and column position.

<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 object that indicates whether each photo is available or not. The JSON string contains information like:

[{"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}]

To highlight the available photos in the HTML, I need to parse this JSON and add a class of "photo-available" if the "available" property is true. Being new to Angular, I'm unsure about how to achieve this easily. Any guidance on what methods or directives to use would be appreciated.

Edit: The Angular code snippet for reference:

<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>                          

Answer №1

Latest Update
If you are facing difficulties in restoring previous selections, it might be due to the fact that you are overwriting the selected property of the photo using ng-init:

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

By setting photo.selected to false with ng-init, the 'selected' class will not be applied because of this hardcoded value. Simply removing ng-init should allow ng-class to function correctly and add the appropriate class for previous selections.

You can see a functional demonstration here: http://plnkr.co/tVdhRilaFfcn55h6mogu

Initial Solution
In case your list of photos is different from the available photos array, you can utilize a custom directive to apply the necessary 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');
      }
    }
  }
});

To implement this directive, simply attach it to each list item as shown below:

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

For a live demo, check out: http://plnkr.co/WJCmLf2M39fcUnvOPyNA

Recent Updates

After reviewing your latest update, it appears that there is only one array populating both the list and the availability status. Therefore, utilizing ngClass directly without a custom directive should suffice. Here's how you can integrate it into your code snippet:

<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>

The plunker has been updated to showcase this functionality.
http://plnkr.co/WJCmLf2M39fcUnvOPyNA

Additional Update
To handle multiple classes with ngClass, use the following syntax:

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

See an illustration combining selected and available classes here: http://plnkr.co/WJCmLf2M39fcUnvOPyNA

Answer №3

Here is a solution that should fit all of your criteria:

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

You can then utilize ng-repeat to generate the list:

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

This code loops through the image array and assigns each element to the variable image. If image.available is true, it adds the class photo-available to that item.

The ID and text for each item are generated based on their row and position properties ({{image.row}}{{image.position}}). You could also concatenate them with a plus sign like this: {{image.row + image.position}}, but be cautious if they are both numerical values.

http://plnkr.co/edit/abc123xyz987

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When utilizing KineticJS on a canvas that has been rotated with css3, the functionality of the events appears to be malfunctioning

Currently, I'm working on a rotating pie-chart widget using Kineticjs. However, I have run into an issue where the events don't seem to function correctly when drawing on a rotated canvas element (with the parent node being rotated 60deg using CS ...

The problem arises when Angular's $interval function is not recognized

Despite the possibility of this being considered a duplicate, none of the related topics have provided a solution to my simple date count down directive: class Clock { constructor() { this.restrict = 'AC'; this.replace = true ...

Troubleshooting Next.js 13: Issues with Error and Not Found Pages Rendering Incorrectly

I am currently working on a project with the latest version of Next.js, specifically Next.js 13, and I have organized my app directory structure accordingly. Within the app/sample directory, I have implemented custom error handling by creating pages named ...

Find all the different ways that substrings can be combined in an array

If I have a string input such as "auto encoder" and an array of strings const arr = ['autoencoder', 'auto-encoder', 'autoencoder'] I am looking to find a way for the input string to match with all three values in the array. ...

The functionality of the Ajax form is limited to a single use

Here's how my script is currently looking. Yes, it comes from a plugin. No, I'm not very familiar with ajax. Is there a way for me to make this form refresh and be ready to accept input again after the first submission? <script> jQuery(do ...

Angular: Using ng-blur to toggle visibility between elements

I'm having trouble toggling the visibility of these divs: <div class="desc" ng-show="desc"> and displaying this div <div class="lists" ng-show="lists" ng-repeat="x in todoWork | orderBy:['todoPriority', 'todoTime&ap ...

Steps to Create an HTML Text Box that cannot be clicked

Does anyone know of a way to prevent a text box from being clicked without disabling it or blocking mouse hover events? I can't disable the text box because that would interfere with my jQuery tool tips, and blocking mouse hover events is not an opti ...

I am seeking the original XML element with the exact tagName, including proper case sensitivity

Below is a code snippet that retrieves and displays the UpperCase text of tagNames. I am looking to work with the original case. var xml = '<myElements type="AA" coID="A923"><myHouse>01</myHouse> <myCars>02</myCars><m ...

Downloading EJS File instead of Displaying on Express.js Router

As I embark on the journey of developing a live video sharing/watching feature using Pure Node.js and without relying on any frameworks, an unexpected issue arose in the middle of the process. The problem occurred when Express started downloading an EJS fi ...

What is the best way to transfer information from a service to my controller?

Currently, I am experimenting with the Ionic framework and learning AngularJS simultaneously. I have been working on implementing $q and asynchronous calls but facing some challenges. My goal is to parse a JSON file using GetJsonSpecials, pass it to GetDat ...

Unclear error message encountered with Rails server

Currently using OS X Sierra I'm managing a rails app with front-end and back-end components. The back-end is built on rails 4, while the front-end utilizes Angular. To run the server locally for development or testing purposes, I typically need to ha ...

The files fail to respond after executing npm and initiating npm starts

I'm completely new to AngularJS. When I run npm start, the server status shows "serving from :. /" but it doesn't seem to pick up the file even though I've specified the file name as index.html. Can someone please assist me in resolving this ...

Make sure to always select the alternative option in ajax

I am trying to create a condition where if the value of id=type_investor is either 1 or 6, an email should be sent using a different controller. Here is my complete code: function (isConfirm) { if (!isConfirm) return; $.ajax({ ...

Assign the chosen item once the information has been retrieved from the server

When working with AngularJS, what is the recommended approach for loading initial data and setting selected options? For instance, let's consider two services: Service for loading initial configuration app.service('ConfigService', function ...

Exploring AngularJS capabilities: iterating over a collection of objects generated by a method

My latest project involves retrieving data from an API using a controller. Here's the code snippet: .controller('MyDataController', ['$http', function($http) { pdc = this; pdc.projects = [] pdc.getData = function(val ...

Receiving an inaccurate value from the input with type='number' attribute

There is an input field where users can enter a string, and I need to capture the value entered into it. $("#test").on("change", function(){ console.log($(this).val()); }) <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery ...

Create a POST request to the server using Express.js

I'm facing a minor problem with something I had assumed was doable. I am aiming to create two express routes – one as a GET route named /post-data and another as a POST route called /post-recieve. The code snippet would appear like the following: ...

Setting the state based on Promise values within a loop

I am currently facing a challenge in my React project where I am using axios to interact with an external API. The goal is to loop through the array of objects retrieved from the API call and utilize the values returned by a separate function within the ...

Dayjs is failing to retrieve the current system time

Hey everyone, I'm facing an issue with using Dayjs() and format to retrieve the current time in a specific format while running my Cypress tests. Despite using the correct code, I keep getting an old timestamp as the output: const presentDateTime = da ...

What is the process for getting the input value when a key is released?

My goal is to capture the actual value or text from an input field and store it in a variable. However, when I use the console to check the output, it shows me a number indicator that increments each time I type something. <input id="usp-custom-3" ty ...