1

With the onclick event I am trying to add mutliple LIs to UL, It wont add more than one Li with this method no matter how many appendChilds I do.

var form = document.getElementById("form");
var newUl = document.createElement('ul');
var newLi = document.createElement('li');

newButton.addEventListener("click", function(){
form.appendChild(newUl);
newUl.id = "formList";
var formList = document.getElementById("formList");
formList.appendChild(newLi);
formList.appendChild(newLi);
formList.appendChild(newLi);
}

//// html
<div id="form">

 </div>
2
  • You are trying to add the same instances, try to create new li instances inside the event listener Commented Sep 2, 2016 at 3:01
  • "li" has been a document fragment when it append to form.You should create new li again. Commented Sep 2, 2016 at 3:06

5 Answers 5

5

newLi is a reference to the node you wish to append to the formList. It can exist just once.

So, first time it executes formList.appendChild(newLi), it will append it to formList. Second time it executes, it would be removed from the first position and now added to second position. Same for third position.

You cannot append the same node multiple times using appenChild.

The Node.appendChild() method adds a node to the end of the list of children of a specified parent node. If the given child is a reference to an existing node in the document, appendChild() moves it from its current position to the new position (there is no requirement to remove the node from its parent node before appending it to some other node). This means that a node can't be in two points of the document simultaneously. So if the node already has a parent, the node is first removed, then appended at the new position.

Description at MDN

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for this detailed explanation +1
3

You have to make a separate element each time.

Try this:

var form = document.getElementById("form");

function newLi() {
    return document.createElement("li");
    }

newButton.addEventListener("click", function(){
    //Create a separate <ul> each time, give it a class, and add it.
    var newUl = document.createElement("ul");
    newUl.class = "formList";
    form.appendChild(newUl);

    //create new <li>'s and append them
    formList.appendChild(newLi());
    formList.appendChild(newLi());
    formList.appendChild(newLi());

    //smile. :D
    }

Unlike Muhammad, I assume that you want to create a separate unordered list (<ul>) each time.

Hence, whenever the button is clicked, we add a new <ul> and then append our <li>s into the new <ul>.

2 Comments

@FransB: Good. Is that what you wanted?
pretty much, except I only want one UL so I kept the var newUl outside the event, I know there's not much point to doing this for one Ul but im experimenting with dynamic lists.
1
var form = document.getElementById("form");
var newUl = document.createElement('ul');

newUl.id = "formList";
form.appendChild(newUl);

newButton.addEventListener("click", function(){
    var newLi = document.createElement('li');
    newUl.appendChild(newLi);
})
  • You need to create the ul once, and assign to it the id = "formList", then append it to the form
  • On every click, create new li element
  • You don't need to select the ul again, because you already has a reference to it.

Here you can find a working fiddle https://jsfiddle.net/LeoAref/m5d0bzeL/

Comments

0

There's too much to correct in your post all at once. But if you're trying to template your LI, you can clone it using cloneNode

var template_ul = document.createElement('ul');
var template_li = document.createElement('li');
let newButton = document.getElementById('new');
var count = 0;

newButton.addEventListener("click", function() {
  let list = template_ul.cloneNode();
  document.getElementById('form').appendChild(list);

  
  let first_li = template_li.cloneNode();
  var text = document.createTextNode(++count);
  first_li.appendChild(text);
  
  list.appendChild(first_li);
  list.appendChild(template_li.cloneNode());
  list.appendChild(template_li.cloneNode());
});
body { 
  text-align:center;
}
button { margin: 4px auto 1em; }

ul {
  margin: 0 auto 1em;
  padding: 0;
  width: 50%
}

ul:nth-child(2n) li{
  background:#c90;
}


li {
  list-style-type: none;
  background: #09c;
  height: 20px;
  padding: 2px;
}

ul,
li {
  border: 1px solid #444;
}
<button id="new">New</button>
<div id="form">
</div>

Comments

0
function addNode(){
  var x = document.createElement("ul");
  x.setAttribute("id","myList");
  document.body.appendChild(x);

  var myListItem = document.createElement("li");
  var textNode = document.createTextNode("List Item one");
  var t2 = document.createTextNode("second item");

  myListItem.appendChild(textNode);

  document.getElementById("myList").appendChild(newLi("FirstItem"));
  document.getElementById("myList").appendChild(newLi("Second Item"));
  document.getElementById("myList").appendChild(newLi("Third Item"));
  document.getElementById("myList").appendChild(newLi("Fourth Item"));
}

//function which generates a new li tag and accepts a string for TextNode
    function newLi(x)
    {
      var m = document.createElement("li");
      var t = document.createTextNode(x);
      m.appendChild(t);
      return m;
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.