Generating dynamic HTML using Javascript based on a multidimensional array

Looking to create some dynamic HTML based on a multidimensional array? That's exactly what I'm trying to do. While handling a one-dimensional array is easy, the varying depth of this array structure presents a challenge.

I should mention that I prefer accomplishing this task without any external JavaScript libraries.

Here's an example of the array I'm working with:

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 array format follows:

[string "type" [, json obj "attributes" ][, string "text"][, array "children"]]


I already have a function that creates a single element from an array:

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;
}


My goal now is to loop through all the "children" and their descendants as shown in the sample array. The desired output would be structured 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. When the array can have multiple levels, what's the best approach for traversing through the children and all sub-children?
  2. Should I call the createEl() function recursively to generate and append those child elements?
    • Is this even feasible?
  3. Would restructuring the array like this help?:
    [string "type" [, json obj "attributes" [, string "text" [, array "children"]]]]
  4. Is there a more efficient way to achieve this without relying on jQuery or similar libraries? (subjective, but seeking advice from experienced developers)


Appreciate your insights!

Answer №1

  1. To properly configure your createEl function, ensure it is set up in a recursive manner. This means that if there are nested children, the function will be called recursively for each child.

  2. Agree with point 1.

  3. The choice is yours to make.

  4. In this scenario, I believe using jQuery may not offer any significant benefits. It would be helpful to delve into the concept of recursion and implement it in JavaScript syntax.

Check out a helpful resource here

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

When the menu mobile is open, I successfully disable scrolling on the body, but I am facing an issue where the desktop page always jumps back to the top

I successfully disabled the scroll on the body, thanks to helpful advice from SO! However, I encountered an issue where the body kept jumping back to the top whenever I opened my mobile menu. If I remove the following code: overflow: hidden;</P </bl ...

Displaying information from a JSON file on a Bootstrap 4 Carousel with jQuery, complete with image references

I am attempting to parse a JSON file from my local files and in console.log I can see the array, but I'm not sure how to display it in the Bootstrap carousel to showcase the data. My goal is to retrieve JSON files and only display those that start wit ...

Using Ajax with Controller Action in Yii2

As a newcomer to programming, I am facing an issue where I need to call a function when the user inputs data and clicks the submit button. Although I am working with Yii2, I lack experience in Ajax. Despite my efforts, the controller action is not being tr ...

Leverage JavaScript to insert the text of an HTML element attribute into another HTML element

Is there a way to access the message using JavaScript in order to write it to the heading tag? Below is my HTML code: <h1 message = "this is the title of the page"></h1> The message needs to be displayed under specific conditions. I ...

using flexbox in react does not automatically resize

I am attempting to create a layout where the screen is split into two sections - one green block taking up 1/4 of the screen and one yellow block taking up 3/4 of the screen using react.js. However, when I tried implementing the code below, both blocks end ...

Am I causing my entire React component to re-render needlessly every time the state changes?

I've been attempting to develop an accordion component using React, but I seem to be encountering issues with the animation not functioning as expected. The approach I'm taking is quite standard - setting a max-height of 0 for each item body and ...

User update function is not being triggered by Ionic 2 Express call

I am currently working on implementing a feature in my Ionic 2 program that updates a user field when triggered. The code snippet below is from my user-service.ts file: // Update a user update(user: User): Observable<User> { let url = `${this.u ...

Smoothness issue with fading in Ajax-loaded div using jQuery

When I run the code locally, the fade-in effect is very smooth. However, when it's deployed on a remote server, the content loaded into the target div initially appears, then disappears instantly before fading back in again. What could be causing thi ...

axios does not distinguish between response and error in its return value

I have created a React component that contains a function called onFormSubmit. This function calls another function from a separate component, which in turn makes a POST request using axios. I want the ability to return a response if the POST request is su ...

Storing an array in Firestore

I am currently struggling with using Firestore to store data on a webpage. I am attempting to store an array of custom objects, but for some reason Firestore is not allowing me to do so. I have attempted to pass it as an object of objects, but it keeps g ...

What happens when we combine "document.getElementById" with "$(this).parent().trigger('submit')"?

In the code below, there is a form for users to input their information. When a user clicks on the submit button, I need help writing the script correctly in order to successfully call both events. <script> $('.submitbutton').click(function ...

CAUTION: Attempted to load angular multiple times while loading the page

I encountered a warning message while working on my project, causing errors in calling backend APIs due to duplicate calls. Despite attempting previously suggested solutions from the forum, I am stuck and seeking assistance. Can anyone provide guidance? Be ...

transform two series of data into a single object - JavaScript

I'm struggling to merge two arrays into a single array object. Here is the first array, referred to as "keys". Each item in this array should become an object key: ["name", "age", "gender", "status"] The second array contains values and is named "h ...

Using jasmine-node to create a spy on a constructor invoked within another function

As a beginner in Jasmine, I am looking to write unit tests for a node.js application using this framework. However, I am facing some challenges, one of which is described below: var sampleFunction = function(){ var loader = new Loader(params); // ...

Capture user input to extract data from a JavaScript object

I need help with implementing a search function where users can enter a name and the person's extension will be displayed on the UI either by clicking a button or pressing "return". Any ideas on how to make this feature work seamlessly? UI <html ...

The child component is not updating the v-model prop array of the parent component

In my current project, I have a main component called cms-custom-editor: <template> <div id="cms-custom-editor" class="cms-custom-editor"> <cms-editor-toolbar v-model:toggles="state.toggles"/> <d ...

The implementation of merge sort becomes challenging due to the method of variable storage

Despite having experience in C++ and Python, I've been grappling with understanding merge sort. I grasp the concept, but I'm puzzled by how Python handles the values. To simplify things, I decided to focus on sorting only [11, 26, 9]. Specifical ...

Remove a specific item from a MongoDB Collection using its ID

I have a MongoDB collection named "Members" which stores data for each member including first name, last name, and an autogenerated Object ID. I am able to retrieve the data using ExpressJS and display it with VueJS. While my get and post methods are worki ...

The AJAX request using JSONP encounters an issue where the error callback is not defined

My ajax call seems to be encountering a problem. Although I am confident that the headers are correct because accessing the URL directly provides me with a response similar to: jsonpCallback({"id":"274"}) However, upon making the ajax call, an error is th ...

Patience is key as you await the element to load and smoothly render the data in vue.JS

Is there a way to ensure that the graph is only rendered and filled with data after the data has been returned from the backend? Currently, even though the data is returned, the graph appears blank. Here is my JavaScript code: methods: { refresh( ...