Q:

Convert DOM childs to JSON

var allmenus = $('.dragger-menu').map(function() {
  var li = {};
  $(this).children('li').each(function() {
    switch ($(this).data("menu")) {
      case "page":
        li.page = {
          id: $(this).data("menu-id")
        };
        break;
      case "external-link":
        li["external-link"] = {
          title: $(this).text().trim(),
          url: $(this).data("menu-link"),
          icon: $(this).children("i").attr("class")
        }
        break;
      case "dropdown":
        li.dropdown = {};
        li.dropdown.title = $(this).contents().filter(function() {
          return this.nodeType == Node.TEXT_NODE;
        }).text().trim();
        li.dropdown.data = $(this).children("ol").map(function() {
          var data = {};
          $(this).children("li").each(function() {
            switch ($(this).data("menu")) {
              case "page":
                data.page = {
                  id: $(this).data("menu-id")
                };
                break;
              case "external-link":
                data["external-link"] = {
                  title: $(this).text().trim(),
                  url: $(this).data("menu-link"),
                  icon: $(this).children("i").attr("class")
                }
                break;
            }
          });
          return data;
        }).get();
        break;
    }
  });
  return li;
}).get();

var obj = {
  menu: allmenus
};
var jsondata = JSON.stringify(obj, null, 2);
console.log(jsondata);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ol class="dragger-menu">
   <li class="list-group-item" data-menu="page" data-menu-id="24">Online Register</li>
   <li class="list-group-item" data-menu="page" data-menu-id="26">Secondly Page</li>
   <li class="list-group-item" data-menu="dropdown">
      <i class="fa fa-caret-square-o-down"></i> Dropdown Menu 
      <ol class="">
         <li class="list-group-item" data-menu="page" data-menu-id="25">Contact Us</li>
         <li class="list-group-item" data-menu="external-link" data-menu-link="https://twitter.com/your-page"><i class="fa fa-Twitter"></i> Twitter</li>
         <li class="list-group-item" data-menu="external-link" data-menu-link="https://facebook.com/your-page"><i class="fa fa-Facebook"></i> Facebook</li>
      </ol>
   </li>
</ol>
<ol class="dragger-menu">
   <li class="list-group-item" data-menu="page" data-menu-id="28">Ahmet Deneme</li>
   <li class="list-group-item" data-menu="page" data-menu-id="21">Secondly Page</li>
</ol>

The above javascript code does not pass the same type element to json. Example: If you are run the code, you see only page 26, not 24. This code only get last elem in same elem. I want the all elements in json data. What should i do in javascript code ? Sorry for my bad englısh . Thanks for all.

A:

Don't build JSON by concatenating strings. Create an object and then use JSON.stringify.
And use jQuery's .each() and .map() methods to loop through the DOM, rather than for loops.

var allmenus = $('.dragger-menu').map(function() {
  var li = {};
  $(this).children('li').each(function() {
    switch ($(this).data("menu")) {
      case "page":
        li.page = {
          id: $(this).data("menu-id")
        };
        break;
      case "external-link":
        li["external-link"] = {
          title: $(this).text().trim(),
          url: $(this).data("menu-link"),
          icon: $(this).children("i").attr("class")
        }
        break;
      case "dropdown":
        li.dropdown = {};
        li.dropdown.title = $(this).contents().filter(function() {
          return this.nodeType == Node.TEXT_NODE;
        }).text().trim();
        li.dropdown.data = $(this).children("ol").map(function() {
          var data = {};
          $(this).children("li").each(function() {
            switch ($(this).data("menu")) {
              case "page":
                data.page = {
                  id: $(this).data("menu-id")
                };
                break;
              case "external-link":
                data["external-link"] = {
                  title: $(this).text().trim(),
                  url: $(this).data("menu-link"),
                  icon: $(this).children("i").attr("class")
                }
                break;
            }
          });
          return data;
        }).get();
        break;
    }
  });
  return li;
}).get();

var obj = {
  menu: allmenus
};
var jsondata = JSON.stringify(obj, null, 2);
console.log(jsondata);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ol class="dragger-menu">
  <li class="list-group-item" data-menu="page" data-menu-id="24">Online Register</li>
  <li class="list-group-item" data-menu="external-link" data-menu-link="https://facebook.com/your-page"><i class="fa fa-facebook"></i> Facebook</li>
  <li class="list-group-item" data-menu="dropdown">
    <i class="fa fa-caret-square-o-down"></i> Dropdown Menu
    <ol class="">
      <li class="list-group-item" data-menu="page" data-menu-id="25">Contact Us</li>
      <li class="list-group-item" data-menu="external-link" data-menu-link="https://twitter.com/your-page"><i class="fa fa-Twitter"></i> Twitter</li>
    </ol>
  </li>
</ol>
<ol class="dragger-menu">
  <li class="list-group-item" data-menu="page" data-menu-id="28">Ahmet Deneme</li>
</ol>

The code to get the title of the dropdown came from How to get the text node of an element?. It would be easier if you put that text inside a <span> so you can write a selector for it.

