Search code examples
javascriptdom

DOM Manipulation cloning nodes and placing values


I am trying to dynamically create a list, by cloning a li item, and then dynamically fill in the values of that list. Strangely, I get only the second item out of my object in that list. I have tried to review the code I wrote, but I cannot seem to find the issue?

Fiddle: https://jsfiddle.net/qaktdgb2/

<ul>
    <li>{name},{price}</li>
</ul>
    
<script>
function loop(node) {

  value = [{
      name: 'Bananas',
      price: '4'
    },
    {
      name: 'Candy',
      price: '2'
    },
    {
      name: 'Oranges',
      price: '2'
    },
    {
      name: 'Vegetables',
      price: '5'
    }
  ]

  let obj = Object.entries(value);
  let len = Object.entries(value).length;

  for (let k = 0; k < value.length; k++) {

    let object = Object.entries(obj[k][1]);

    for (const property in object) {

      let search = `${object[property]}`;
      let values = Object.entries(search.split(','));


      let textName = values[0][1];
      console.log(textName + ':' + values[1][1]);

      let regex = new RegExp("{\\s*" + textName + "[0-9]*\\s*}", "i");

      if (node.childNodes[k].innerHTML) {
        node.appendChild(node.childNodes[k].cloneNode(true));
        node.childNodes[k].innerHTML = node.childNodes[k].innerHTML.replace(regex, values[1][1]);
      }
    }
  }
}

function nodeParentList() {
  let parentList = [];
  var docElements = document.getElementsByTagName("*")
  for (var i = 0; i < docElements.length; i++) {
    parentList.push(docElements[i]);
  }
  return parentList;
}


var docElements = nodeParentList();
for (var i = 0; i < docElements.length; i++) {
  loop(docElements[i]);
}

</script>

Expected:

  • Bananas
  • Candy
  • Oranges
  • Vegetables

  • Solution

  • You were doing some weird things, that I even gave up to understand. So I've changed almost everything. So:

    • you can use querySelector rather than getElementsByTagName like in jQuery, just for ease of understanding.
    • nodeParentList function is useless, because you are creating an array, that has all elements of the second array. You already have an array, this step is not neccesary.
    • Why use RegExp here? It's slow and bad. Better to split it yourself by hand.
    • Why use Object.entries? You can just .forEach through the array.
    • You are non-stop using node.childNodes[k]. You can first assign it to a variable.

    soooo.... I've rewrote the code for you lol, to match all these requirements + contain the fix

    HTML

    <ul>
      <li>{name},{price}</li>
    </ul>
    

    JavaScript

    function loop(node) {
      let values = [{
          name: 'Bananas',
          price: '4'
        },
        {
          name: 'Candy',
          price: '2'
        },
        {
          name: 'Oranges',
          price: '2'
        },
        {
          name: 'Vegetables',
          price: '5'
        }
      ];
    
      let child = node.children[0];
      let syntax = child.innerHTML;
      values.forEach(obj => {
        if (child.innerHTML) {
          child.innerHTML = syntax.replace("{name}", obj.name).replace("{price}", obj.price);
          node.append(child);
          child = child.cloneNode(true);
        }
      });
    }
    
    loop(document.querySelector("ul"));