Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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!

share|improve this question
    
Don't reinvent the wheel at least in templating case. Have a look at template plugins for JS –  redV Mar 1 at 21:05
2  
Also, this is a tiny pedantic comment but technically you should put class on line 5 of template in quotes because it is actually a reserved word in JS (sorry) –  user2521439 Mar 1 at 21:12
    
@redV - I didn't mention this in my question but this is sort of an exercise for me... Reinventing the wheel is kinda what I'm shooting for here. ;) –  DondeEstaMiCulo Mar 1 at 21:14
    
@user2521439 Agreed! I don't actually have class in my code, but I did fail to encapsulate that in my example. Thanks for pointing that out! –  DondeEstaMiCulo Mar 1 at 21:16
    
@DondeEstaMiCulo That's ok :) Just saw it and made me think - I believe the class keyword is being implemented in ES6 –  user2521439 Mar 1 at 21:17
add comment

1 Answer

up vote 1 down vote accepted
  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

share|improve this answer
1  
I'm going to check that out right now. Thanks for the help! –  DondeEstaMiCulo Mar 1 at 21:03
1  
Took me a minute to get my head wrapped around this, but once I did it worked perfectly. Thanks for the steering me in the right direction! –  DondeEstaMiCulo Mar 4 at 5:15
    
I love your attitude! –  alexK85 Mar 4 at 5:38
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.