user256430
user256430

Reputation: 3633

Create HTML with JavaScript from a multidimensional array

As the title says, I am trying to write a function which would create some HTML based on the array I feed it. If the array were simply one dimensional, I wouldn't have any problems. But the "multidimensionality" of the array is where I'm having issues. Namely since it's not always consistent.

I should also note that I am trying to accomplish this without any 3rd party JS libraries.

For example, here is a sample array:

var template = [
    ['div', {id: 'wrapper'}, [
        ['link', {rel:'stylesheet', href:'//mysite.com/css.css', type:'text/css'}],
        ['header', "Look at me!  I'm a header!"],
        ['nav', {class:'main-nav'}, [
            ['ul', [
                ['li', ['a', {'href':'/home'}, "Home"]],
                ['li', ['a', {'href':'/about'}, "About Us"]],
                ['li', ['a', {'href':'/erase_internet.php'}, "Don't click me!"]]
            ]]
        ]],
        ['section', "Some sample text!"],
        ['footer', "Copyright © 1984"]
    ]]
];


The format of the array is:
[string "type" [, json obj "attributes" ][, string "text"][, array "children"]]


Now I already have one function which takes a single array object and creates an element:

function createEl(type, attr, text) {
    var key, el = d.createElement(type);

    if (typeof attr === 'object' && !Array.isArray(attr)) {
        for (key in attr) {
            if (attr.hasOwnProperty(key)) {
                el.setAttribute(key, attr[key]);
            }
        }
    }
    else if (typeof attr === 'string' && text.length > 0) {
        el.appendChild(d.createTextNode(attr));
    }

    if (typeof text === 'string' && text.length > 0) {
        el.appendChild(d.createTextNode(text));
    }

    return el;
}


But I want to be able to process all of the "children" and append them to their parents, as indicated by the sample array, so that the output would look like this:

<div id="wrapper">
    <link rel="stylesheet" href="//mysite.com/css.css" type="text/css" />
    <header>Look at me!  I'm a header!</header>
    <nav class="main-nav">
        <ul>
            <li><a href="/home">Home</a></li>
            <li><a href="/about">About us</a></li>
            <li><a href="/erase_internet.php">Don't click me!</a></li>
        </ul>
    </nav>
    <section>Some sample text!</section>
    <footer>Copyright &copy; 1984</footer>
</div>


So here are my questions:

  1. If I don't know how many levels deep the array goes, what's the best-practice method for traversing through the children and all of the grand-children?
  2. Would I call the createEl() function again from within itself to create and append those children elements, if they exist?
    • Is that even possible?
  3. Would it help at all if I changed the structure of the array to this?:
    [string "type" [, json obj "attributes" [, string "text" [, array "children"]]]]
  4. Is there maybe a better way of doing this altogether, without having to resort to jQuery or the like? (subjective, but I value the expertise and experience of the SO Community)


Many thanks in advance!

Upvotes: 2

Views: 553

Answers (1)

alexK85
alexK85

Reputation: 93

  1. You will need to setup your createEl in a recursive fashion. So, if you have deeper children, the function is triggered recursively for those children.

  2. Yes, look at 1.

  3. Your preference.

  4. I don't think, but not sure, that jQuery would buy you anything in your case. My suggestion is to look up how recursion works as an idea and apply it to JavaScript syntax.

A good place to get started

Upvotes: 1

Related Questions