Show javascript object in ul list recursively

I am trying to display a JavaScript object in an HTML module ul. The object represents a binary tree and has this format:

{
    "val":2,
    "l":{
        "val":1,
        "l":{},
        "r":{}
    },
    "r":{
        "val":4,
        "l":{},
        "r":{
            "val":5,
            "l":{},
            "r":{}
        }
    }
}

As a result, I have to do the following:

<ul>
    <li>
        <a href="#">2</a>
        <ul>
            <li>
                <a href="#">1</a>
            </li>
            <li>
                <a href="#">4</a>
                <ul>
                    <li>
                        <a href="#">5</a>
                    </li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

I wrote this code here to get the corresponding result string, but it does not generate the correct result.

function buildList(data){
    var html = '';
    if(data.val){
        if(data.l){
            html += '<ul>';
            html += buildList(data.l);
        }
        html += '<li>';
        html += '<a href="#">' + data.val + '</a>'
        html += '</li>';
        if(data.r){
            html += buildList(data.r);
            html += '</ul>';
        }
    }

    return html;
}

Any guesses or hints would be appreciated.

+4
source share
4 answers

You can use a dynamic recursive approach by creating DOM nodes with the desired object.

function buildDOM(tree) {
    function buildLI(node) {
        var li = document.createElement('li'),
            a = document.createElement('a');

        a.href = '#';
        a.appendChild(document.createTextNode(node.val));
        li.appendChild(a);
        if (('l' in node) && ('val' in node.l) || ('r' in node) && ('val' in node.r)) {
            li.appendChild(buildDOM(node));
        }
        return li;
    }

    var ul = document.createElement('ul');                

    if (('l' in tree) && ('val' in tree.l)) {
        ul.appendChild(buildLI(tree.l));
    }
    if (('r' in tree) && ('val' in tree.r)) {
        ul.appendChild(buildLI(tree.r));
    }
    return ul;
}

var data = { val: 2, l: { val: 1, l: {}, r: {} }, r: { val: 4, l: {}, r: { val: 5, l: {}, r: {} } } };

document.body.appendChild(buildDOM({ r: data }));  
Run codeHide result
+1
source

Make life easy

, looooong. , if .

, if/else. , runnable demo


(), val {}, l r - . , :

const makeTree = ({val, l, r}) => {
  if (val === undefined)
    return []
  else
    return [Node('ul', Node('li', Link('#', val)), ...makeTree(l), ...makeTree(r))]
}

, Node Link. , , makeTree , . , - HTML. makeMenu - , , node .toElem()

const makeMenu = data =>
  makeTree(data)[0].toElem()

, .toElem node Node Link. , , , , , (), .


Node Link

Node Link. . Node - HTML- type, ; , .toElem. Link href text .

const Node = (type, ...children) => ({
  toElem: () => {
    const elem = document.createElement(type)
    children.forEach(child => elem.appendChild(child.toElem()))
    return elem
  }
})

const Link = (href, text) => ({
  toElem: () => {
    const elem = document.createElement('a')
    elem.setAttribute('href', href)
    elem.textContent = text
    return elem
  }
})

const Node = (type, ...children) => ({
  toElem: () => {
    const elem = document.createElement(type)
    children.forEach(child => elem.appendChild(child.toElem()))
    return elem
  }
})

const Link = (href, text) => ({
  toElem: () => {
    const elem = document.createElement('a')
    elem.setAttribute('href', href)
    elem.textContent = text
    return elem
  }
})

const makeTree = ({val, l, r}) => {
  if (val === undefined)
    return []
  else
    return [Node('ul', Node('li', Link('#', val)), ...makeTree(l), ...makeTree(r))]
}

const makeMenu = data =>
  makeTree(data)[0].toElem()

const data = { "val": 2, "l": { "val": 1, "l": {}, "r": {} }, "r": { "val": 4, "l": {}, "r": { "val": 5, "l": {}, "r": {} } } }

document.body.appendChild(makeMenu(data))
Hide result
+2

. :

function buildList(data){
    var html = '';
    if(data.val){
        html += '<ul><li>';
        html += '<a href="#">' + data.val + '</a>'
        html += '</li>';
        if(data.l){
            html += buildList(data.l);
        }
        if(data.r){
            html += buildList(data.r);
            html += '</ul>';
        }
    }

    return html;
}

var resultDiv = document.getElementById('resultDiv');

var testData = 
    {
        "val":2,
        "l":{
            "val":1,
            "l":{},
            "r":{}
        },
        "r":{
            "val":4,
            "l":{},
            "r":{
                "val":5,
                "l":{},
                "r":{}
            }
        }
    };
    
resultDiv.innerHTML = buildList(testData);
<p>Actual Result:</p>
<div id="resultDiv">...</div>

<hr>

<p>Desired Result:</p>
<ul>
    <li>
        <a href="#">2</a>
        <ul>
            <li>
                <a href="#">1</a>
            </li>
            <li>
                <a href="#">4</a>
                <ul>
                    <li>
                        <a href="#">5</a>
                    </li>
                </ul>
            </li>
        </ul>
    </li>
</ul>
Hide result
0
var dom = buildList(yourObject);
final(dom);

function buildList(data){
    if(data.val){       
        var currentTag = document.createElement('li');
        var atag = document.createElement('a');
        atag.setAttribute("href", "#");
        atag.innerText = data.val;
        currentTag.appendChild(atag);
        if(JSON.stringify(data.l) != "{}" || JSON.stringify(data.r) != "{}"){           
            var ulTag = document.createElement('ul');
            if(JSON.stringify(data.l) != "{}"){
                ulTag.appendChild( buildList(data.l));
            }
            if(JSON.stringify(data.r) != "{}"){
                ulTag.appendChild( buildList(data.r));
            }
            currentTag.appendChild(ulTag);
        }
    }

    return currentTag;
}

function final(body) {
   body = document.createElement('ul').appendChild(body);
}
0

Source: https://habr.com/ru/post/1675374/


All Articles