Dynamic nested ul\li list from json data using Javascript

14,223

Solution 1

Try this:

var data = [{"id": "1", "name": "name_1", "parent_id": "0", "depth": "0"},
    {"id": "2", "name": "name_2", "parent_id": "0", "depth": "0"},
    {"id": "3", "name": "name_3", "parent_id": "1", "depth": "1"},
    {"id": "4", "name": "name_4", "parent_id": "3", "depth": "2"}];

var initLevel = 0;

var endMenu =getMenu("0");

function getMenu( parentID ){
       return data.filter(function(node){ return ( node.parent_id === parentID ) ; }).map(function(node){
           var exists = data.some(function(childNode){  return childNode.parent_id === node.id; });
           var subMenu = (exists) ? '<ul>'+ getMenu(node.id).join('') + '</ul>' : "";
           return '<li>'+node.name +  subMenu + '</li>' ;
       });
 }
console.log( '<ul>'+endMenu.join('')+ '</ul>');

However, I think the correct output based on your data will be something like:

    <ul>
        <li>name_1
            <ul>
                <li>name_3
                    <ul>
                        <li>name_4</li>
                    </ul>
                </li>
            </ul>
        </li>
        <li>name_2</li>
    </ul>

Here is the JSFiddle sample

Updated Version:

http://jsfiddle.net/LqES7/47/

Solution 2

I'd first convert the flat data to hierarchical json, using something like this, so it's more iterable. Then recursively iterate the JSON and add every element to a string.

Share:
14,223

Related videos on Youtube

Yaroslav Basovskyy
Author by

Yaroslav Basovskyy

Updated on June 05, 2022

Comments

  • Yaroslav Basovskyy
    Yaroslav Basovskyy almost 2 years

    I need to create a dynamic nested ul\li list from json array.

    NOTE! I can do that transformation my self using jQuery, but in this case i need to work with a string, since it's node.js and i don't have access to DOM.

    Also the array can have different depth.

    This is json data i work with and how it should look after transformation.

    var data = [{"id": "1", "name": "name_1", "parent_id": "0", "depth": "0"},
            {"id": "2", "name": "name_2", "parent_id": "0", "depth": "0"},
            {"id": "3", "name": "name_3", "parent_id": "1", "depth": "1"},
            {"id": "4", "name": "name_4", "parent_id": "3", "depth": "2"}];
    
    <ul>
      <li>name_1</li> //depth 0
      <li>name_2  //depth 0
        <ul>
          <li>name_3 //depth 1
            <ul>
              <li>name_3</li> //depth 2
            </ul>
          </li>
        </ul>
      </li>
    </ul>
    

    I hope this is clear. If not please ask any questions in the comment. Thank you in advanced.

  • Yaroslav Basovskyy
    Yaroslav Basovskyy over 10 years
    Hello again. After a little playing with this i found that it has a bug. Try to change third line parent_id to 2 and it's not working(( If you have any thoughts, please help.
  • Dalorzo
    Dalorzo over 10 years
    @user2960708 found it, I updated both the fiddle and the answer
  • Yaroslav Basovskyy
    Yaroslav Basovskyy over 10 years
    Yes, now it's working. Thank you. But i have one more challenge. I'm building sortable nested menu. And when i'm changing the order of element it isn't changing in db. So, i've added index value to each element and now i need to change the function to sort elements according to that index. It would be grate if you have any thoughts ))
  • Yaroslav Basovskyy
    Yaroslav Basovskyy over 10 years
    yes, i just getting the index of li according to it siblings and saving it to db. It looks like this now {"id": "1", "name": "name_1", "parent_id": "0", "depth": "0", index: 0}
  • Yaroslav Basovskyy
    Yaroslav Basovskyy over 10 years
    Yes))) Thank you very much. You're the best)
  • Monzurul Haque
    Monzurul Haque over 9 years
    I am having problem with this example. Please check this fiddle jsfiddle.net/LqES7/16 and tell me why it's getting the extra "," between two same level li tag
  • Dalorzo
    Dalorzo over 9 years
    @MonzurulHaque there is .join() missing in the inner getMenu this version: jsfiddle.net/LqES7/47