Md Mahfuzur Rahman Md Mahfuzur Rahman - 20 days ago 8
Javascript Question

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.

Answer

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.

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>

Comments