简体   繁体   中英

Multi-dimensional array or json object from nested list item in JS

I've a nested list items. I want to make an multi-dimensional array or json object from the list items. I've tried something like below. But I'm not getting the expected output.

The depth of the list item can be more. So, I'll define a recursive method to do this later.

DEMO Fiddle

HTML:

<div class="dd" id="nestable">
    <ol class="dd-list">
        <li class="dd-item" data-id="1">
            <div class="dd-handle">Sub-indicator 1</div>
            <ol class="dd-list">
                <li class="dd-item" data-id="2">                    
                    <div class="dd-handle">Sub-indicator 2</div>
                    <ol class="dd-list">
                        <li class="dd-item" data-id="3">

                            <div class="dd-handle">Sub-indicator 3</div>
                            <ol class="dd-list">
                                <li class="dd-item" data-id="4">

                                    <div class="dd-handle">Sub-indicator 4</div>
                                </li>
                            </ol>
                        </li>
                    </ol>
                </li>
                <li class="dd-item" data-id="3">

                            <div class="dd-handle">Sub-indicator 3</div>
                            <ol class="dd-list">
                                <li class="dd-item" data-id="4">

                                    <div class="dd-handle">Sub-indicator 4</div>
                                </li>
                            </ol>
                        </li>
            </ol>
        </li>
    </ol>
</div>

JS:

var subIndicTreeObj = {};
var tempObj = [];
var parentId = 0;
var parentId1 = 0;
var parentId2 = 0;

$('#nestable > ol > li').each(function(index, value) { 
    parentId = 0;
    parentId1 = 0;
    parentId2 = 0;

    tempObj.push({'sub_indic_id': $(this).attr('data-id'), 'parent_id': parentId});


    if ($(this).has('ol').length > 0) { 

        parentId = $(this).attr('data-id');

        $(this).find('ol > li').each(function(index1, value1) { 

            tempObj.push({'sub_indic_id': $(this).attr('data-id'), 'parent_id': parentId});


            if ($(this).has('ol').length > 0) {  

                parentId1 = $(this).attr('data-id');

                $(this).find('ol > li').each(function(index2, value2) { 

                    tempObj.push({'sub_indic_id': $(this).attr('data-id'), 'parent_id': parentId1});

                    if ($(this).has('ol').length > 0) { 


                        parentId2 = $(this).attr('data-id');

                        $(this).find('ol > li').each(function(index3, value3) { 

                            tempObj.push({'sub_indic_id': $(this).attr('data-id'), 'parent_id': parentId2});

                        });
                    }

                });
            } 
        });
    } 
});

subIndicTreeObj = tempObj;

console.log(subIndicTreeObj);

Current Output:

 [
  Object{
    sub_indic_id="1",
    parent_id=0
  },
  Object{
    sub_indic_id="2",
    parent_id="1"
  },
  Object{
    sub_indic_id="3",
    parent_id="2"
  },
  Object{
    sub_indic_id="4",
    parent_id="3"
  },
  Object{
    sub_indic_id="4",
    parent_id="2"
  },
  Object{
    sub_indic_id="3",
    parent_id="1"
  },
  Object{
    sub_indic_id="4",
    parent_id="3"
  },
  Object{
    sub_indic_id="4",
    parent_id="1"
  },
  Object{
    sub_indic_id="3",
    parent_id="1"
  },
  Object{
    sub_indic_id="4",
    parent_id="3"
  },
  Object{
    sub_indic_id="4",
    parent_id="1"
  }
]

I want the immediate parent_id of a child. But I'm getting the top level parent_id for some list item. Such as,

Object{
    sub_indic_id="4",
    parent_id="1"
  }

Can anybody help to find out the problem ? Thanks in advance.

I didn't understand if it's the expected behaviour, anyway, it's recursive, and also find the first child. I just added a > before the ol > li selector.

Note that i also added a data-id='0' to id="nestable" to get the first parent id.

edit

For more detail about > selector as asked in comment, i suggest to have look to some documentation. I mostly learned from w3school . Reporting from that link

The element>element selector is used to select elements with a specific parent.

So, in your code with ol > li you were retriving all the li children of every ol , contained in $(this) .

With > ol > li you retrive the direct children of the object on which you're searching, and not also the children of chidren.

 var subIndicTreeObj = []; function findLiChild($obj, parentId) { $obj.find('> ol > li').each(function(index1, value1) { subIndicTreeObj.push({ 'sub_indic_id': $(this).attr('data-id'), 'parent_id': parentId }); findOlChild($(this)); }); } function findOlChild($obj) { if ($obj.has('ol').length > 0) { findLiChild($obj, $obj.attr('data-id')); } } findOlChild($('#nestable')); console.log(subIndicTreeObj); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="dd" id="nestable" data-id="0"> <ol class="dd-list"> <li class="dd-item" data-id="1"> <div class="dd-handle">Sub-indicator 1</div> <ol class="dd-list"> <li class="dd-item" data-id="2"> <div class="dd-handle">Sub-indicator 2</div> <ol class="dd-list"> <li class="dd-item" data-id="3"> <div class="dd-handle">Sub-indicator 3</div> <ol class="dd-list"> <li class="dd-item" data-id="4"> <div class="dd-handle">Sub-indicator 4</div> </li> </ol> </li> </ol> </li> <li class="dd-item" data-id="3"> <div class="dd-handle">Sub-indicator 3</div> <ol class="dd-list"> <li class="dd-item" data-id="4"> <div class="dd-handle">Sub-indicator 4</div> </li> </ol> </li> </ol> </li> </ol> </div> 

Try a simple loop:

var data = [];//create the array
$('.dd-item').each(function() {//loop each item
  var parent = $(this).parent().closest('.dd-item');//get the parent
  var parent_id = 0;//set 0 if it has no parent
  if (parent.length) {
    parent_id = parent.attr('data-id');//set parent id if it has
  }
  data.push({
    parent_id: parent_id ,sub_indic_id: $(this).attr('data-id')
  });//append to the array
});
console.log(data);

demo: https://jsfiddle.net/uwqqmz86/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM