Home > Net >  Vanilla JS: Rendering a <template> tag with a Javascript object
Vanilla JS: Rendering a <template> tag with a Javascript object

Time:03-29

Say one has an html template like this:

<template id="template">
    <div id="A"></div>
    <div id="B"></div>
    <div id="C"></div>
    <div id="D"></div>
    <div id="E"></div>
    <div id="F"></div>
</template>

Now when one clones to add it to the DOM with JavaScript, I have not come across a "nice" way to fill in all the blanks, this seems very verbose:

const object = {A:1, B:2, C:3, D:4, E:5, F:6};
const template = document.getElementById("template")
let newThing = template.cloneNode(true);
newThing.getElementById("A").innerHTML = object.A;
newThing.getElementById("B").innerHTML = object.B;
newThing.getElementById("C").innerHTML = object.C;
newThing.getElementById("D").innerHTML = object.D;
newThing.getElementById("E").innerHTML = object.E;
newThing.getElementById("F").innerHTML = object.F;
container.appendChild(newThing);

I understand one could drop the <template> and move it all into JavaScript, but I am hesitant, because I like to keep HTML in HTML files, then you have linting in the text editor etc..

To me this is not a great solution since now the HTML is living in script files:

const newThing = `
<div>
    <div>${object.A}</div>
    <div>${object.B}</div>
    <div>${object.C}</div>
    <div>${object.D}</div>
    <div>${object.E}</div>
    <div>${object.F}</div>
</div>

Is there a better way to render a template with an object of data? I have read up on lithtml, but a whole library to do this one little thing seems like overkill.

CodePudding user response:

This is one possible solution, however it is not exactly advised depending on what you are trying to do

If you'd like, you can create a template with an ID in your HTML like so:

<template id="myTemplate">
        <div>${object.A}</div>
        <div>${object.B}</div>
        <div>${object.C}</div>
        <div>${object.D}</div>
        <div>${object.E}</div>
        <div>${object.F}</div>
</div>

And then call eval inorder to parse it

eval('`'   document.getElementById("myTemplate").innerHTML   '`')

This returns the formatted code that you can then place in your document

Why shouldn't you use this?

Eval is pretty dangerous, and if used wrong someone can execute dangerous commands on behalf of your website. If this is some personal project you can use this if you'd like, but preferably not on some larger scale public use website.

CodePudding user response:

The object's key-value pairs can be used directly inside a for-in loop. This allows markup stored in an object of anylength to be assigned to an html collection where each element's ID is the same as the key value of the corresponding data object.

for (const property in object) {
newThing.getElementById(property).innerHTML = object[property];
}

In the above code, 'property' is the key name of each of the objects properties and so object[property] is a direct reference to its value.

I've used this in a working snippet below to render some arbirary html stored in an object:

const container = document.getElementById("container");

const object = {
  A:"<h2>my heading</h2>", 
  B:"<a href='https://www.google.com'>Google Search</a>", 
  C:"<p>Computing is enjoyable <i>and</i> frustrating<p>", 
  D:"<div> what\'s your name ? <input type='text'></div>", 
  E:"<p>another paragraph</p>", 
  F:"<h2>goodbye!</h2>"
}
const template = document.getElementById("template")
let newThing = template.content.cloneNode(true);

for (const property in object) {
newThing.getElementById(property).innerHTML = object[property];
}

container.appendChild(newThing);
<template id="template">
    <div id="A"></div>
    <div id="B"></div>
    <div id="C"></div>
    <div id="D"></div>
    <div id="E"></div>
    <div id="F"></div>
</template>

<div id="container"></div>

  • Related