0

In short I want to convert a UL list to a javascript/jquery array. My issue is that the UL can be of any length and depth of nesting.

here is a sample UL:

<div id="main">
  <ul>
    <li>
      <span>HOME</span>
      <ul>
        <li><span>Page 1</span></li>
        <li><span>Page 2</span></li>
        <li>
          <span>Page 3</span>
          <ul>
            <li><span>Page a</span></li>
            <li><span>Page b</span></li>
            <li><span>Page c</span></li>
            <li>
              <span>Page X</span>
              <ul>
                <li><span>Page d</span></li>
                <li><span>Page e</span></li>
                <li><span>Page f</span></li>
                <li><span>Page g</span></li>
              </ul>
            </li>
          </ul>
        </li>
        <li><span>Page 4</span></li>
     </ul>
    </li>
   </ul>
 </div>

I have a basic each loop in jquery that only goes through the first nested. I need it to keep going through any li that has children and the array generated to match the nesting format:

var arr = [];
    $("#main > ul > li").each(function() {
        var elem = {
            brand: $(this).find(">span:first").text(),
            children: []
        };
        $(this).find(">ul>li").each(function() {
             elem.children.push($(this).find('span:first').text());
        });
        arr.push(elem);
    });
console.log(arr);

Here is what it outputs:

enter image description here Any help would be gratefully received. I get the feeling I just need some sort of function that keeps on looping down a li's until it comes back false to having any child ul/li.

2
  • 1
    Please add the expected output for your markup. Commented Jan 23, 2018 at 10:08
  • This is my problem the UL size and nesting depth can be anything. The output array needs dynamic to match the nesting format of the UL. Commented Jan 23, 2018 at 10:14

1 Answer 1

2

The best way to achieve what you want is through recursion:

var list = [];
$("#main > ul > li").each(function() {
    list.push(buildObject($(this)));
});

function buildObject(parent){
  var obj = {
    brand: parent.find(">span:first").text(),
    children: [],
  }
  parent.find(">ul>li").each(function() {
     obj.children.push(buildObject($(this)));
  });
  return obj;
}

console.log(list);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="main">
  <ul>
    <li>
      <span>HOME</span>
      <ul>
        <li><span>Page 1</span></li>
        <li><span>Page 2</span></li>
        <li>
          <span>Page 3</span>
          <ul>
            <li><span>Page a</span></li>
            <li><span>Page b</span></li>
            <li><span>Page c</span></li>
            <li>
              <span>Page X</span>
              <ul>
                <li><span>Page d</span></li>
                <li><span>Page e</span></li>
                <li><span>Page f</span></li>
                <li><span>Page g</span></li>
              </ul>
            </li>
          </ul>
        </li>
        <li><span>Page 4</span></li>
     </ul>
    </li>
   </ul>
 </div>

Sign up to request clarification or add additional context in comments.

1 Comment

That is what I was trying to think of! works like a charm! Thanks you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.