0

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>

1 Answer 1

1

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.

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

2 Comments

I see, i guess i was on the right path. So everything outside is simply being "cached" on load? Thanks for the quick and extensive reply, it worked!
Hey, no problem. "Cache" would be the wrong word though. You might say that the browser stores to memory, that value of global variable userInput as "", a blank string. Any function that references userInput will get that stored value. The value stored to memory remains there as long as the user does not reload the page (or exit the browser).

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.