简体   繁体   中英

HTML generation from Javascript nested object

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM