NakoNachev
NakoNachev

Reputation: 53

JS: Add list element with dynamic text input

What i have: small script which appends list elements when the user clicks on a button with .

What i want: The user can dynamically type input and the input will be used as a text for the list element

What doesn't work: It does not save the value from the input, it always shows empty. I suspect it has something to do with the data not being loaded and still using the default, but i am not sure.. Started with js a couple of days ago, so i am fairly new with the DOM concepts.

var userInput = document.getElementById("userChoice").value;
var textNodeValue = userInput;

// remove a list element when the user clicks on remove item
function deleteElement(clicked_id) {
  //save list element
  var clickedButton = document.getElementById(clicked_id);
  console.log(clickedButton);
  var parentNodeLi = clickedButton.parentElement;
  var listElement = parentNodeLi.parentElement;
  listElement.removeChild(parentNodeLi);
}

// adds a new list item
function addListItem(textNodeValue) {
  //add list item, button and image to button
  var newElem = document.createElement("li");
  var newButton = document.createElement("button");
  var newImage = document.createElement("img");

  //add text nodes
  var newNode = document.createTextNode(textNodeValue);
  var newNodeButton = document.createTextNode("");
  newImage.src = "button_delete.jpg"; //add src for image 
  newImage.height = 15;

  //add id to the button
  var nodeList = document.getElementsByTagName("li");
  var idIncrementor = nodeList.length + 1;
  console.log(idIncrementor);


  newButton.setAttribute("id", "button".concat(idIncrementor));
  console.log(newButton.getAttribute("id"));

  //add anonymous function to the evenListerner to call the deleteElement function
  //use it for parameter to the onclick function
  newButton.addEventListener('click', function() {
    deleteElement(newButton.getAttribute("id"))
  });

  // add the image for the button
  newButton.appendChild(newImage);

  //append text node and button to the new list element
  newElem.appendChild(newNode);
  newElem.appendChild(newButton);

  //get the unorderedList and append the new list
  var unorderedList = document.getElementById("list");
  unorderedList.appendChild(newElem);
}
<div id="newItemContainer">
  <input id="userChoice">
  <button onclick="addListItem(textNodeValue)">Add item </button>
</div>
<div id="shoppingListContainer">
  <ul id="list">
    <li>List 1 <button class="listItems" id="button1" onclick="deleteElement(this.id)"><img src="button_delete.jpg" height=15/> </button> </li>
    <li>List 2 <button class="listItems" id="button2" onclick="deleteElement(this.id)"><img src="button_delete.jpg" height=15/> </button></li>
    <li>List 3 <button class="listItems" id="button3" onclick="deleteElement(this.id)"><img src="button_delete.jpg" height=15/> </button></li>
    <li>List 4 <button class="listItems" id="button4" onclick="deleteElement(this.id)"><img src="button_delete.jpg" height=15/></button></li>
  </ul>
</div>

Upvotes: 0

Views: 1453

Answers (1)

Dakshraj Sharma
Dakshraj Sharma

Reputation: 151

you're running into this issue, likely because of an unclear understanding of how JS scripts are handled by html.

Basically, when the html page loads up, it loads the JS file, and "executes" it line by line. Everything that is not inside a function, gets executed and values hence any vars that are at the script root (outside of any functions) get evaluated right then. What this means for you is that the vars userInput and textNodeValue get assigned values as soon as the JS loads, and that value is the default, a blank string, as you correctly thought.

Instead of having the values for these vars being assigned as soon as the JS loads, what you should do is move the two lines of code from the top to inside function addListItem. Hence, your function should become:

function addListItem() {
    var userInput = document.getElementById("userChoice").value;
    var textNodeValue = userInput;

    // so on

By doing this, what happens is that JS reads the value of the input at the time of the user clicking the "Add Item", hence achieving what you want.

Upvotes: 1

Related Questions