skip to Main Content

I have an array of objects. I have to somehow process this data and create an HTML document. I have no problems with HTML and CSS, but don’t know where to start with JS and how to process the data. I don’t even understand how to describe my problem correctly in order to Google some similar solutions. Can anyone help me to make a plan what exactly I should do?

I’ve made a picture describing the logic. When users click the button, they’ll see a menu (in a block looks like a dropdown menu), then they can go through category and select the item they want to choose. Please note that there’s only one block, in the pic I’m just showing the logic. After that, below the user can see the list of items they selected

const menu = [{
  categories: [{
    id: 1,
    name: 'Desserts',
    categories: [{
      id: 2,
      name: 'Ice cream',
      categories: [{
        id: 3,
        name: 'Vanilla',
        categories: []
      }, {
        id: 4,
        name: 'Strawberry',
        categories: []
      }]
    }, {
      id: 5,
      name: 'Baked apples',
      categories: []
    }]
  }, {
    id: 6,
    name: 'Coffee',
    categories: []
  }, {
    id: 7,
    name: 'Tea',
    categories: [{
      id: 8,
      name: 'Green tea',
      categories: [{
        id: 9,
        name: 'With Jasmine',
        categories: []
      }, {
        id: 10,
        name: 'Simple',
        categories: []
      }]
    }, {
      id: 11,
      name: 'Black Tea',
      categories: []
    }]
  }]
}]

3

Answers


  1. Below I show you the one of sample logic. You can add more looping and styles as per the level of categories and requirements you have;

    var objData= JSON.parse(aResultData);
    var sHtml  = '<ul>';
    
    for(var i=0; i<objData.length; i++) {
     sHtml = sHtml + '<li>'+objData[i].name+'</li>';
    
     if (objData[i].categories.length>0) {
      for(var j=0; j<objData[i].categories.length; j++) {
       if (j==0) {
        sHtml = sHtml + '<ul>'+objData[j].name+'</ul>';
       } else {
        sHtml = sHtml + '<li>'+objData[j].name+'</li>';
       }
       if (objData[j].categories.length>0) {
        for(var k=0; k<objData[j].categories.length; k++) {
         if (k==0) {
          sHtml = sHtml + '<ul>'+objData[k].name+'</ul>';
         } else {
          sHtml = sHtml + '<li>'+objData[k].name+'</li>';
         }
        }
       }
      }
     }
    }
    sHtml = sHtml + '</ul>';
    
    Login or Signup to reply.
  2. In this approach, I first flatten your object structure assigning each item a reference to its parent’s ID.

    The array structured this way easily allows you to filter "subitems".

    const menu = [{
      categories: [{
        id: 1,
        name: 'Desserts',
        categories: [{
          id: 2,
          name: 'Ice cream',
          categories: [{
            id: 3,
            name: 'Vanilla',
            categories: []
          }, {
            id: 4,
            name: 'Strawberry',
            categories: []
          }]
        }, {
          id: 5,
          name: 'Baked apples',
          categories: []
        }]
      }, {
        id: 6,
        name: 'Coffee',
        categories: []
      }, {
        id: 7,
        name: 'Tea',
        categories: [{
          id: 8,
          name: 'Green tea',
          categories: [{
            id: 9,
            name: 'With Jasmine',
            categories: []
          }, {
            id: 10,
            name: 'Simple',
            categories: []
          }]
        }, {
          id: 11,
          name: 'Black Tea',
          categories: []
        }]
      }]
    }]
    
    
    
    const m = menu[0].categories
    
    
    // THIS WILL BE THE FLAT ARRAY OF ITEMS IN MENU
    let arr = []
    
    
    // ITERATE ROOT CATEGORIES
    for (let cat of m) {
      // FOR EACH CATEGORY, CALL THE RECURSIVE FUNCTION
      recurCats(cat, 0)
    }
    
    
    // HERE IS THE FLAT ARRAY
    console.log(arr)
    
    
    const level0 = arr.filter(item => item.parentID == 0).map(item => '<option data-id="' + item.id + '" value="' + item.name + '">' + item.name + '</option>')
    
    document.getElementById('s1').innerHTML = '<option value="0">Select an item</option>' + level0.join('')
    
    
    document.getElementById('s1').addEventListener('change', function() {
      let thisID = this.options[this.selectedIndex].getAttribute('data-id')
    
      const level1 = arr.filter(item => item.parentID == thisID).map(item => '<option data-id="' + item.id + '" value="' + item.name + '">' + item.name + '</option>')
    
      document.getElementById('s2').innerHTML = '<option value="0">Select an item</option>' + level1.join('')
    
    })
    
    
    document.getElementById('s2').addEventListener('change', function() {
      let thisID = this.options[this.selectedIndex].getAttribute('data-id')
    
      const level2 = arr.filter(item => item.parentID == thisID).map(item => '<option data-id="' + item.id + '" value="' + item.name + '">' + item.name + '</option>')
    
      document.getElementById('s3').innerHTML = '<option value="0">Select an item</option>' + level2.join('')
    
    })
    
    
    // RECURSIVE FUNCTION
    function recurCats(cat, parentID) {
      arr.push({
        name: cat.name,
        id: cat.id,
        parentID: parentID
      })
    
      if (cat.hasOwnProperty('categories') && cat.categories.length > 0) {
        for (let subcat of cat.categories) {
          recurCats(subcat, cat.id)
        }
      }
    }
    <select id="s1"></select>
    
    <select id="s2"></select>
    
    <select id="s3"></select>
    Login or Signup to reply.
  3. first step : change jo object to HTML UL / LI

    recursive method=

    const menu = 
      [ {                                           categories: 
          [ { id: 1,          name: 'Desserts',     categories: 
              [ { id: 2,      name: 'Ice cream',    categories: 
                  [ { id: 3,  name: 'Vanilla',      categories: [] } 
                  , { id: 4,  name: 'Strawberry',   categories: [] } 
                ] } 
              , { id: 5,      name: 'Baked apples', categories: [] } 
            ] } 
          , { id: 6,          name: 'Coffee',       categories: [] } 
          , { id: 7,          name: 'Tea',          categories: 
              [ { id: 8,      name: 'Green tea',    categories: 
                [ { id: 9,    name: 'With Jasmine', categories: [] } 
                , { id: 10,   name: 'Simple',       categories: [] } 
                ] } 
              , { id: 11,     name: 'Black Tea',    categories: [] } 
      ] } ] } ] 
         
    let menuEl = document.querySelector('nav')
    
    addElements( menuEl, menu[0].categories )
    
    function addElements(parent, arr)   // UL /LI buider
      {
      let ul = parent.appendChild(document.createElement('ul'))
      arr.forEach(el => 
        {
        let li = ul.appendChild(document.createElement('li'))
        li.dataset.id  = el.id
        li.textContent = el.name
        if (el.categories.length > 0) addElements(li, el.categories)
        })
      }
      nav ul
        {
        list-style: none;
        }
    <nav></nav>

    second step: make some CSS choices for presentations…

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search