Search code examples
javascriptjsondommultidimensional-arraynested-loops

JavaScript: Modifying DOM and populating it with JSON data


first time asking for help so if I need to present myself in a specific section please point it out!

As said in the title, i've got a JSON data base, and need to populate a website with it's content. It's the first time a try doing something like this (still learning JS). Here is an image of the expected result. If you prefer, this is the expected output in HTML:

<div class="cardsection">
  <div class="card"> 
    <div class= "photoandname">
      <div class="profilphoto">
      </div>
      <h2 class="name"> </h2>
    </div>
    <div class="informations">
      <h3 class="location"> </h3>
      <p class="caption"> </p>
      <p class="price"> </p>
    </div>
    <div class="tags">
      <button class="tagButton"> </button>
      <button class="tagButton"> </button>
     </div>
  </div>
</div>

The problems I have are :

  1. For the Tag section, each card doesn't have the same number of tags. I understand that i need a nested loop, to access the nested array in the JSON data. I tried somethings out but didn't fully manage nor understand how that works so could one of you guys help me out and explain or show me?

  2. Also i keep having an error for the "for" section of my Items loop ( Cannot read property 'length' of undefined) wich I don't get as the property is defined just above (var items = json.items;)

  3. I'm not 100% sure my code is correct. Coded as I did, is it going to properly create each card with it's children ? ( without the identic classnames between cards mislead the appending? And with the aria-labels properly set?)

HTML code : <div class="cardsection"> </div>

JS code :

var json = {
  "photographers": [
    {
      "name": "jonna",
      "id": 125,
      "city": "paris",
      "country": "UK",
      "tags": ["portrait", "events", "travel", "animals"],
      "tagline": "Doing my best",
      "price": 400,
      "portrait": "MimiKeel.jpg"
    }
    ]};
    

var cardsection = document.getElementsByClassName("cardsection")[0];

var items = json.items;
for(var i = 0; i < items.length; i++) {
  
var cards = document.createElement("div");
  cards.classList.add('card');
    cards.setAttribute("aria-label", "Photographe card");
  cardsection.appendChild(cards);
  
var photoandname = document.createElement("div");
  photoandname.classList.add('photoandname');
  photoandname.setAttribute("aria-label", "Profil photo and name section");
  photoandname.innerHTML = items[i].portrait;
  cards.appendChild(photoandname);
  
   //ariel and alt to check

 var profilphoto = document.createElement("img");
 profilphoto.src = items[i].portrait;
 profilphoto.alt = "Photographer's profil image";
 profilphoto.classList.add('profilphoto');
 profilphoto.innerHTML 
 photoandname.appendChild(profilphoto);
  
  var name = document.createElement("h2");
  name.classList.add('name');
  name.innerHTML = items[i].name;
  divphotoname.appendChild(name);
  
  var informations = document.createElement("div");
  informations.classList.add('informations');
  card.appendChild(informations);
  
    var location = document.createElement("h3");
  location.classList.add('location');
  location.innerHTML = items[i].city + items[i].country;
  informations.appendChild(location);
  
      var caption = document.createElement("p");
  caption.classList.add('caption');
  caption.innerHTML = items[i].tagline;
  informations.appendChild(caption);
  
        var price = document.createElement("p");
  price.classList.add('price');
  price.innerHTML = items[i].price; 
  informations.appendChild(price);
  
          var tags = document.createElement("div");
  tags.classList.add('tags');
  
 var tagItems = json.items[i].tags;
for(var j = 0; j < tagItems.length; j++) {
  var tagButton = document.createElement(button);
  tagButton.classList.add('tagButton');
  tagButton.id = tagItems[j]; /*ID needs to be the tag itself for a further filter functionality*/
  tagButton.innerHTML = tagItems[j]; /*And setting the innerhtml of the button as the tag itself*/
  tags.appendChild(tagButton);
  
}   
  card.appendChild(tags); 
}

Thanks for any help and advice you can give me


Solution

  • https://jsfiddle.net/chille1987/s35qz4wf/

    Javascript

    const jsonFile = { 
        "photographers": [
            {
                "name": "jonna",
                "id": 125,
                "city": "paris",
                "country": "UK",
                "tags": ["portrait", "events", "travel", "animals"],
                "tagline": "Doing my best",
                "price": 400,
                "portrait": "MimiKeel.jpg"
            }
         ]
    };
    
    
    var cardsection = document.getElementsByClassName("cardsection")[0];
    
    var items = jsonFile;
    console.log(items.photographers.length);
    
    for(var i = 0; i < items.photographers.length; i++) {
      
      var card = document.createElement("div");
      card.classList.add('card');
      card.setAttribute("aria-label", "Photographe card");
      cardsection.appendChild(card);
      
      var photoandname = document.createElement("div");
      photoandname.classList.add('photoandname');
      photoandname.setAttribute("aria-label", "Profil photo and name section");
      photoandname.innerHTML = items.photographers[i].portrait;
      card.appendChild(photoandname);
      
      var profilphoto = document.createElement("img");
      profilphoto.src = items.photographers[i].portrait;
      profilphoto.alt = "Photographer's profil image";
      profilphoto.classList.add('profilphoto');
      photoandname.appendChild(profilphoto);
      
      var photographerName = document.createElement("H2");
      photographerName.classList.add('name');
      photographerName.textContent = items.photographers[i].name;
      photoandname.appendChild(photographerName);
      
      var informations = document.createElement("div");
      informations.classList.add('informations');
      card.appendChild(informations);
      
      var caption = document.createElement("p");
      caption.classList.add('caption');
      caption.textContent = items.photographers[i].tagline;
      informations.appendChild(caption);
      
      var price = document.createElement("p");
      price.classList.add('price');
      price.innerHTML = items.photographers[i].price; 
      informations.appendChild(price);
      
      var tags = document.createElement("div");
      tags.classList.add('tags');
      
        var tagItems = items.photographers[i].tags;
      console.log(tagItems)
      for(var j = 0; j < tagItems.length; j++) {
        
        var tagButton = document.createElement('button');
        tagButton.classList.add('tagButton');
        tagButton.id = tagItems[j]; /*ID needs to be the tag itself for a further filter functionality*/
        tagButton.textContent = tagItems[j]; /*And setting the innerhtml of the button as the tag itself*/
        tags.appendChild(tagButton);
    
      }   
      card.appendChild(tags);
    }