Reputation: 3
really need your help. I'm trying to write a function that would generate HTML markup from javascript object.
My thoughts is I send an object and a root element as parameters and recursively append elements.
Here is the code.
const struct = [
{
tag: 'div',
classes: ['container'],
innerHtml: [
{
tag: 'input',
classes: ['input'],
attributes: [
['type', 'text'],
['placeholder', 'Some input']
]
},
{
tag: 'div',
classes: ['btn-block'],
innerHtml: [
{
tag: 'div',
classes: ['btn', 'btn-long'],
innerText: 'Long Button'
},
{
tag: 'div',
classes: ['btn', 'btn-big', 'btn-img'],
innerHtml: [
{
tag: 'img',
attributes: [
['src', 'https://www.w3schools.com/images/w3certified_logo_250.png']
],
}
],
}
]
},
{
tag: 'div',
classes: ['red']
}
]
}
];
const root = document.body;
function create(obj, root) {
obj.forEach(o => {
const element = document.createElement(o.tag);
if (o.classes) {
const classes = o.classes;
element.classList.add(...classes);
}
if (o.attributes) {
o.attributes.forEach(a => {
element.setAttribute(a[0], a[1]);
})
}
if (o.hasOwnProperty('innerHtml')) {
element.append(create(o.innerHtml, element));
}
if (o.innerText) {
element.innerText = o.innerText
}
root.append(element);
});
}
create(struct, root);
And there is a result;
As you can see the function add text 'Undefined' to every element.
Could you help me to fix it?
UPD: Solved by answers from @CertainPerformance and @Nina Scholz
Upvotes: 0
Views: 58
Reputation: 370699
The problem is
element.append(create(o.innerHtml, element));
But create
doesn't return anything, so undefined
is appended to the end of every element. Change to just
create(o.innerHtml, element)
instead:
const struct = [{
tag: 'div',
classes: ['container'],
innerHtml: [{
tag: 'input',
classes: ['input'],
attributes: [
['type', 'text'],
['placeholder', 'Some input']
]
},
{
tag: 'div',
classes: ['btn-block'],
innerHtml: [{
tag: 'div',
classes: ['btn', 'btn-long'],
innerText: 'Long Button'
},
{
tag: 'div',
classes: ['btn', 'btn-big', 'btn-img'],
innerHtml: [{
tag: 'img',
attributes: [
['src', 'https://www.w3schools.com/images/w3certified_logo_250.png']
],
}]
}
]
},
{
tag: 'div',
classes: ['red']
}
]
}];
const root = document.body;
function create(obj, root) {
obj.forEach(o => {
const element = document.createElement(o.tag);
if (o.classes) {
const classes = o.classes;
element.classList.add(...classes);
}
if (o.attributes) {
o.attributes.forEach(a => {
element.setAttribute(a[0], a[1]);
})
}
if (o.hasOwnProperty('innerHtml')) {
create(o.innerHtml, element)
}
if (o.innerText) {
element.innerText = o.innerText
}
if (element !== undefined) {
root.append(element);
}
});
}
create(struct, root);
.container {
padding: 5px;
border: 1px solid black;
display: flex;
justify-content: space-around;
align-items: center;
}
.input {
height: 20px;
width: 200px;
}
.btn-block {
display: flex;
justify-content: space-around;
align-items: center;
}
.btn {
border: 1px solid black;
border-radius: 5px;
padding: 5px 15px;
text-align: center;
}
.btn:hover {
cursor: pointer;
}
.btn-long {
width: 300px;
margin-right: 10px;
}
.red {
background: red;
height: 100px;
width: 100px;
}
Upvotes: 1
Reputation: 386560
You need only
create(o.innerHtml, element);
without wrapping element.append(/* ... */);
because your function does not return somthing.
function create(obj, root) {
obj.forEach(o => {
const element = document.createElement(o.tag);
if (o.classes) {
const classes = o.classes;
element.classList.add(...classes);
}
if (o.attributes) {
o.attributes.forEach(a => {
element.setAttribute(a[0], a[1]);
})
}
if (o.hasOwnProperty('innerHtml')) {
create(o.innerHtml, element);
//element.append();
}
if (o.innerText) {
element.innerText = o.innerText
}
root.append(element);
});
}
const struct = [{
tag: 'div',
classes: ['container'],
innerHtml: [{
tag: 'input',
classes: ['input'],
attributes: [
['type', 'text'],
['placeholder', 'Some input']
]
},
{
tag: 'div',
classes: ['btn-block'],
innerHtml: [{
tag: 'div',
classes: ['btn', 'btn-long'],
innerText: 'Long Button'
},
{
tag: 'div',
classes: ['btn', 'btn-big', 'btn-img'],
innerHtml: [{
tag: 'img',
attributes: [
['src', 'https://www.w3schools.com/images/w3certified_logo_250.png']
],
}],
}
]
},
{
tag: 'div',
classes: ['red']
}
]
}];
const root = document.body;
create(struct, root);
Upvotes: 1