Creating an HTML string from an array in JavaScript

Hi there, I'm in need of some assistance with a JavaScript task. Can anyone help?

I'm looking to create a JavaScript function that can take an array and return the corresponding HTML string.

For example: [tagName, child1, child2, ...]

• The tag name will always be the first entry in the array and will be a string.

• The children can be arrays or strings.

• Strings are treated as plain text, not HTML markup.

• Arrays are considered nested elements.

• No support for attributes, comments, etc., only elements and text.

• Empty tags should be self-closing.

• Consecutive text nodes will be merged in the final output.

No libraries, build processes, or transpilers are permitted.

Examples:

['div']                       => '<div/>'

['h1', 'Text']                => '<h1>Text</h1>'

['span', 'More', 'Text']      => '<span>MoreText</span>'

['a', ['b', 'More'], ' Text'] => '<a><b>More</b> Text</a>'

['p', '<b>Text</b>']          => '<p>&lt;b&gt;Text&lt;/b&gt;</p>'

This is my current code using objects instead of arrays. Any suggestions on how to convert it?

var obj = {
  "h1": 'text',
  "a": {"b": 'more'}, // nested element
  "text": '', // empty tag
  "p": '<b>text</b>' // with HTML
};

var finalString = '';

function createHTML(obj){
  for (var prop in obj) {
    if (obj.hasOwnProperty(prop)) { 

    if (obj[prop] == '[object Object]') {

      finalString += "<" + prop + ">";
      createHTML(obj[prop]);
      finalString += "</" + prop + ">";

    } else {
      if (obj[prop] == '') {
        finalString += "<" + prop + "/>";
      } else {
        finalString += "<" + prop + ">" + encodeURI(obj[prop]) + "</" + prop + ">";
      }
    }
  } 
}
}

createHTML(obj);

console.log(finalString);
// "<h1>text</h1><a><b>more</b></a><text/><p>%3Cb%3Etext%3C/b%3E</p>"

Answer №1

One way to approach this is by using recursion:

  1. Creating DOM element objects :

function genHTML(arr) {
  // create a DOM element object with the first array item
  var element = document.createElement(arr[0]);
  // iterate over the remaining elements
  arr.slice(1).forEach(function(value) {
    // if the item is an array, recursively call the function and append the returned element
    if (Array.isArray(value))
      element.appendChild(genHTML(value));
    // else generate a text node and append
    else
      element.appendChild(document.createTextNode(value));
  })
  // return the reference to the element
  return element;
}


[['div'],['h1', 'Text'],['span', 'More', 'Text'],['a', ['b', 'More'], ' Text'],['p', '<b>Text</b>']].forEach(function(data) { 
  // log the HTML content using outerHTML property
  console.log(JSON.stringify(data) + ' => ' + genHTML(data).outerHTML);
})


  1. Using simple string concatenation.

function genHTML(arr) {
  // generate opening tag
  var string = '<' + arr[0] + '>';
  // iterate over the remaining elements
  arr.slice(1).forEach(function(value) {
    // if the item is an array, recursively call the function and concatenate the returned value
    if (Array.isArray(value))
      string += genHTML(value);
    // else concatenate the string after handling special characters
    else
      string += value.replace(/</g, "&lt;").replace(/>/g, "&gt;");
  })
  // return the result with the closing tag
  return string + '</' + arr[0] + '>';
}

[['div'],['h1', 'Text'],['span', 'More', 'Text'],['a', ['b', 'More'], ' Text'],['p', '<b>Text</b>']].forEach(function(data) { 
  // log the generated markup
  console.log(JSON.stringify(data) + ' => ' + genHTML(data));
})

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

What is the best way to utilize unique slash commands in Slack threads?

After setting up a custom slash command /news in Slack, it appears to work fine. However, I'm struggling to figure out how to trigger slash commands within threads. Whenever I try to use the command, I receive this error message: /news is not support ...

What is the best method for accessing the HTML element specified in React JSX?

Consider this custom component example: import React, { Component } from 'react'; class Canvas extends Component { componentDidMount() { let canvas = this.refs.canvas; const ctx = canvas.getContext('2d'); ctx.fillRect(0, ...

After hiding an element's visibility, getElementById is unable to locate the element

Developing an asp.net page with a master page that utilizes a content page (web control). The web control consists of 4 elements: PickListType dropdown, UserPickList (not important), Organization label, Body label, and Address dropdown. Upon changing the ...

Steer clear of displaying the latest model directly

Currently, I have a form for creating a new Model named Route. This form includes a select field called takeover, which displays all existing Routes for the user to choose from and establish a relationship with the selected Route. The issue I am facing is ...

Utilizing Regex Patterns to Manipulate CSS Attributes

I am dealing with a string containing CSS properties and their values: str = "filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#cccccc', endColorstr='#000000'); background: -webkit-linear-gradient(top, black, wh ...

Conceal the 'Load More' button once the outcome falls under or equals the specified CI limit

I'm struggling with a "load more" button. The button should be hidden if either (1) the result is less than the limit of 20 or (2) there are no more results to display. Despite my efforts, the button remains visible. For instance, in this scenario, t ...

Creating captchas seems like a mistake in reasoning to me

I am encountering an issue with my code. I created a basic newbie-level captcha using Javascript. Below is the code snippet: <!DOCTYPE html> <html> <head> <style> </style> </head> <body> <h1>T ...

Tips for organizing the output of items from the .getJSON method

I am currently facing an issue where my output is displayed on the page in the same order as the raw JSON file. I am seeking assistance on how to sort the items based on a specific property within each item. For instance, I would like to sort alphabetical ...

Enhancing functionality through the press of a button

I wrote a script that, upon button click, finds the closest location to your current position by searching through an array. It then locates the corresponding entry in another array and adds a number to that entry. However, I encountered a problem with app ...

What is causing the bars to move forward on the x-axis starting from the second one?

I have been working on a chart and here is the code I have so far: plot = $.jqplot('SalesChart2', [ [[1,5]], [[1,10]], [[1,15]], [[1,20]], [[2,25]], ...

Exploring Ruby array functions and their results

My task is to develop a code that takes a number as input and returns all the even numbers between 1 and the input number. These numbers are then printed in a specific format as shown below: 22 4444 666666 etc... Below is the code that I have written so ...

Is there a way to extract JSON keys that begin with a numerical value?

I am attempting to retrieve JSON data from sparkfun using ajax: var token = "someToken"; var jsonData = $.ajax({ url: "https://data.sparkfun.com/output/" + token + ".json", data: { page: 1 }, dataType: "jsonp", }).done(function (results) { ...

Clicking the delete button in Firebase to remove an item

I am in the process of developing a simple CRUD application and have opted for Firebase as my backend solution. While I have successfully implemented the create and read functionalities, I've hit a roadblock with the delete operation. When attempti ...

Updating values in mongoDB using Express.js and axios: A step-by-step guide

I need help figuring out how to update a specific post's data in my mongoDB using its object id. I have created an HTML form that displays the selected post's data and allows me to make changes, then submit the updated data to http://localhost:50 ...

Checking the validity of an HTML tag with the contenteditable attribute set to true

Take for instance the input tag, which includes a field known as type. When type is set to "numeric", only numbers can be entered. Now, if I set a td element as contenteditable, is there a way to restrict the user from inputting anything other than number ...

Changing Color of Specific Sticky Note in React - Customize Color of Individual Note Without Affecting Others

In React, I am working on a basic application for sticky notes that allows users to create as many of them as they'd like. One issue I'm facing is with changing the color of individual sticky notes – currently, when I change the color, it affe ...

Service Worker's fetch event is not triggered upon registering the service worker

Service Worker is a new concept to me. As I delved into learning how to incorporate Service Worker into My Next.js Application, I encountered an issue with the fetch event handler. Oddly enough, the fetch event handler doesn't trigger upon initially r ...

Sophisticated filter - Conceal Ancestry

Check out this snippet of my HTML: <td> <a class="button" href="#"> <input id="download">...</input> </a> <a class="button" href="#"> <input id="downloadcsv">...</input> </a> </td> I am ...

Utilizing the Authorization Header in WebSocket within a React Electron Application

Struggling to establish a connection with a secure websocket that requires Bearer Auth via Header. Despite popular advice, it seems setting headers for WebSockets is not straightforward. How can I achieve this in a React Electron App? Currently using the & ...

Updating data in MongoDB using a POST request in Angular 2

I am currently working on implementing a post request to update a value in MongoDB. The scenario involves a user inputting a new value (bitcoin) into a form, which triggers the post request upon submission: bitcoinChange(bitcoin){ let headers = new ...