Sairam
Sairam

Reputation: 29

How to traverse DOM to prepare tree structure array

I want to prepare a nested array by traversing through the DOM using Javascript/jQuery. The elements of interest are in the #container element and either have the dot class or are input elements.

I want to prepare the array like [name,name1,[name2]]. I used here mostly used techniques such as recursion. But I could not get it to work:

fiddle

$(document).ready(function(){
    var arr = [];
    function recurse(parent, arr){
        var temp = [];
        parent.find('*').each(function(){
    	    if($(this).is('input')){
                if($(this).parents('.dot').length==1){
                    console.log($(this));
                    temp.push($(this).attr('id'))
                }
            }
            if($(this).is('.dot')){
                recurse($(this), arr);
            }
        });
        arr.push(temp);
        return arr;
    }
    var elm = $('#container').find('.dot:first');
    console.log(recurse(elm, arr));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
  <div class="dot">
      <div class="dot">
          <input type="password" id="name2" name="name2">	
      </div>
      <input type="text" id="name" name="name">
      <input type="password" id="name1" name="name1">
  </div>
</div>

Upvotes: 1

Views: 192

Answers (2)

Ray Chan
Ray Chan

Reputation: 1180

Here is how you can solve it using vanilla JS

const el = document.querySelector('#container > .dot');

function recurse(containerEl) {
    const result = [];
    const tmp = []; // used to preserve the order [name, name1, [name2]]
    const childrenCollection = containerEl.children;

    for (let i = 0; i < childrenCollection.length; i++) {
        if (childrenCollection[i].tagName === 'DIV') {
            tmp.push(recurse(childrenCollection[i]));
        } else {
            // use this line if you want to fill the array with elements
            // result.push(childrenCollection[i]);

            // use this line if you just want to retrieve the name attribute
            result.push(childrenCollection[i].name);
        }
    }

    return result.concat(tmp);
}

console.log(recurse(el));
<div id="container">
    <div class="dot">
        <div class="dot">
            <input type="password" id="name2" name="name2">
        </div>
        <input type="text" id="name" name="name">
        <input type="password" id="name1" name="name1">
    </div>
</div>

Upvotes: 0

trincot
trincot

Reputation: 350192

Here is how you could make it work. There is no need to pass arr as argument:

function recurse($parent) {
    var arr = [];
    $parent.children('.dot, input').each(function(){
        arr.push($(this).is('input') ? $(this).attr('id') : recurse($(this)));
    });
    return arr;
}

$(function () {
    var elm = $('#container>.dot:first');
    console.log(recurse(elm));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
  <div class="dot">
      <div class="dot">
          <input type="password" id="name2" name="name2">	
      </div>
      <input type="text" id="name" name="name">
      <input type="password" id="name1" name="name1">
  </div>
</div>

Upvotes: 1

Related Questions