0

I made a code in HTML with help from other that will evaluate a list from user input with several functions. The code now will track the sum of all the numbers in the list, the average, the max, min, and frequency of the numbers. The last thing that I want the code to be able to do is to be able to remove items from the list. For example, if the user types in 1,2,3,4,5 and they want to get rid of 3, they could hit a button and 3 would be removed from the list. I'm not exactly sure how to do this, so it would be helpful to receive some help with figuring it out.

.title { font-weight:bold; margin-top:1em; }
<!DOCTYPE html>

<html>

<head>

  <link rel="stylesheet" type="text/css" href="style.css">

</head>


<body>

  <link rel="stylesheet" type="text/css" href="style.css">
  <!--- This only allows the user to input numbers --->

  <input type='number' id='input'>

  <!--- This is the button that adds the number to the list --->

  <input type='button' value='add to list' id='add' disabled="disabled">

  <!--- Here we have a title for the list --->

  <div class="title">Topics</div>

  <!--- This will list all of the numbers --->

  <ul id='list'></ul>

  <!--- When clicked, this buttons alert the user with the numbers --->

  <button id="sum"> Sum </button>
  <button id="max"> Max </button>
  <button id="min"> Min </button>
  <button id="avg"> Avg </button>
  <button id="frequency"> Frequency </button>

  <p><button onclick="lowHigh()">Sort</button></p>


  <div>

    <button value="Refresh Page" onclick="window.location.reload()"> Reset! </button>

  </div>
  
  <script>
    
    let list = document.getElementById("list");
let input = document.getElementById("input");
let add = document.getElementById("add");
var avg = 0;
var sum = 0;
var min = -Infinity;
var max = Infinity;
let frequency = Object.create(null);

// This will add the input number to the list and clear the input

function addClick() {
  var li = document.createElement("li");
  li.textContent = input.value;
  list.appendChild(li);
  update(input.value);
  input.value = "";
  add.disabled = "disabled";

}

// This allows the "add to list" button to be turned on/off depending if the user has typed in a number

function enableDisable() {
  if (this.value === "") {
    add.disabled = "disabled";
  } else {
    add.removeAttribute("disabled");
  }
}

// This will calculate and update all variable values

function update(enteredValue) {
  frequency[enteredValue] = (frequency[enteredValue] || 0) + 1;
  sum = 0;
  min = Infinity;
  max = -Infinity;
  var count = 0;
  for (var i of list.children) {
    let val = +i.textContent;
    sum += val;
    if (val > max) max = val;
    if (val < min) min = val;
    count++;
  }
  avg = sum / count;
}

function frequencyClick() {
  let text = Object.entries(frequency).reduce((a, [number, fqy]) => {
    return a.concat(`The number ${number} appeared ${fqy} time(s) in the list`)
  }, []).join('\n');

  alert(text);
}

// This functions will alert the numbers

function sumClick() {
  alert("The sum of your numbers is: " + sum);
}

function avgClick() {
  alert("The average of your numbers is: " + avg);
}

function minClick() {
  alert("The smaller number is: " + min);
}

function maxClick() {
  alert("The greater number is: " + max);
}

function lowHigh() {
  var list, i, switching, b, shouldSwitch;
  list = document.getElementById("list");
  switching = true;
  /* Make a loop that will continue until
  no switching has been done: */
  while (switching) {
    // Start by saying: no switching is done:
    switching = false;
    b = list.getElementsByTagName("li");
 
    // Loop through all list items:
    for (i = 0; i < (b.length - 1); i++) {
      // Start by saying there should be no switching:
      shouldSwitch = false;
      /* Check if the next item should
      switch place with the current item: */
      if (b[i].innerText > b[i + 1].innerText) {
        shouldSwitch = true;
        break;
      }
    }
    if (shouldSwitch) {
      /* If a switch has been marked, make the switch
      and mark the switch as done: */
      b[i].parentNode.insertBefore(b[i + 1], b[i]);
      switching = true;
    }
  }


}

// Here we add all events

input.addEventListener("input", enableDisable);
add.addEventListener("click", addClick);
document.getElementById("avg").addEventListener("click", avgClick);
document.getElementById("sum").addEventListener("click", sumClick);
document.getElementById("min").addEventListener("click", minClick);
document.getElementById("max").addEventListener("click", maxClick);
document.getElementById("frequency").addEventListener("click", frequencyClick);
    
    
  </script>   


</body>
  

  
  
</html>

2
  • perhaps generate an array of items from the list, remove the desired element from array. Convert array back to string and populate the HTML of 'list' element Commented Mar 22, 2019 at 6:06
  • @MaxMunchnick Please be aware that I changed my answer because there were a few more adaptations necessary to make the work correctly. I overlooked something in my initial post. Commented Mar 22, 2019 at 11:17

1 Answer 1

2

First I modified the addClick() function. I appended a new button to every list element together with an onclick event attached to the button which simply removes the parent element (<li>). Additionally I wrapped the list value in a <span>. This should now serve your purpose well. Every line I modified got a comment in the code below so you get an overview what I have done / changed and why.

function addClick() {
  var li = document.createElement("li");
  var button = document.createElement("button"); //create new button
  var span = document.createElement("span"); //create span which is wrapped around value
  button.onclick = function() { //add onclick event to button
     this.parentNode.remove(this.parentNode); //remove <li> node
     update(this.parentNode.firstChild.innerHTML, true); //update values e.g. frequency, sum, avg
  };
  button.innerHTML = "remove"; //give button a text
  list.appendChild(li);
  span.textContent = input.value; //the value is now added to span
  li.appendChild(span); //add span to li
  li.appendChild(button); //add button to li
  update(input.value);
  input.value = "";
  add.disabled = "disabled";
}

I also modified the update() function and changed the function parameters (signature) to distinguish between deleting and adding of elements. Moreover, I appended some code to adjust the frequency count in case of a delete. It was also necessary to delete the element from frequency if the count = 0. Finally, the line which retrieves the value of a single list element for the arithmetical operations was corrected because the DOM changed as there is a new <span> and <button> element within every <li>.

function update(enteredValue, remove) { //add parameter to know when a frequency should be removed
  if(remove){ // remove frequency
    frequency[enteredValue] = frequency[enteredValue] - 1; //substract by one
    if(frequency[enteredValue] == 0) //if frequency = 0
      delete frequency[enteredValue]; //delete the element
  }else{
    frequency[enteredValue] = (frequency[enteredValue] || 0) + 1;
  }

  sum = 0;
  min = Infinity;
  max = -Infinity;
  var count = 0;
  for (var i of list.children) {
    let val = +i.firstChild.innerHTML; //now retrieve the value from the first child (<span>)
    sum += val;
    if (val > max) max = val;
    if (val < min) min = val;
    count++;
  }
  avg = sum / count;
}

Your list item now after creation looks like this:

<li><span>VALUE</span><button>Remove</button></li>

Update: Initially I overlooked something, my code didn't respect the frequency variable which is modified every time an element is added. I corrected the issue now and changed / extended my explanation. Now the frequency is also correct when elements are removed.


Full Code here:

.title { font-weight:bold; margin-top:1em; }
<!DOCTYPE html>

<html>

<head>

  <link rel="stylesheet" type="text/css" href="style.css">

</head>


<body>

  <link rel="stylesheet" type="text/css" href="style.css">
  <!--- This only allows the user to input numbers --->

  <input type='number' id='input'>

  <!--- This is the button that adds the number to the list --->

  <input type='button' value='add to list' id='add' disabled="disabled">

  <!--- Here we have a title for the list --->

  <div class="title">Topics</div>

  <!--- This will list all of the numbers --->

  <ul id='list'></ul>

  <!--- When clicked, this buttons alert the user with the numbers --->

  <button id="sum"> Sum </button>
  <button id="max"> Max </button>
  <button id="min"> Min </button>
  <button id="avg"> Avg </button>
  <button id="frequency"> Frequency </button>

  <p><button onclick="lowHigh()">Sort</button></p>


  <div>

    <button value="Refresh Page" onclick="window.location.reload()"> Reset! </button>

  </div>
  
  <script>
    
    let list = document.getElementById("list");
let input = document.getElementById("input");
let add = document.getElementById("add");
var avg = 0;
var sum = 0;
var min = -Infinity;
var max = Infinity;
let frequency = Object.create(null);

// This will add the input number to the list and clear the input
function addClick() {
  var li = document.createElement("li");
  var button = document.createElement("button");
  var span = document.createElement("span");
  button.onclick = function() { this.parentNode.remove(this.parentNode); update(this.parentNode.firstChild.innerHTML, true); };
  button.innerHTML = "remove";
  list.appendChild(li);
  span.textContent = input.value;
  li.appendChild(span);
  li.appendChild(button);
  update(input.value);
  input.value = "";
  add.disabled = "disabled";
}

function removeElement(){
  alert("test");
}

// This allows the "add to list" button to be turned on/off depending if the user has typed in a number

function enableDisable() {
  if (this.value === "") {
    add.disabled = "disabled";
  } else {
    add.removeAttribute("disabled");
  }
}

// This will calculate and update all variable values

function update(enteredValue, remove) {
  if(remove){
    frequency[enteredValue] = frequency[enteredValue] - 1;
    if(frequency[enteredValue] == 0)
      delete frequency[enteredValue];
  }else{
    frequency[enteredValue] = (frequency[enteredValue] || 0) + 1;
  }

  sum = 0;
  min = Infinity;
  max = -Infinity;
  var count = 0;
  for (var i of list.children) {
    let val = +i.firstChild.innerHTML;
    sum += val;
    if (val > max) max = val;
    if (val < min) min = val;
    count++;
  }
  avg = sum / count;
}

function frequencyClick() {
  let text = Object.entries(frequency).reduce((a, [number, fqy]) => {
    return a.concat(`The number ${number} appeared ${fqy} time(s) in the list`)
  }, []).join('\n');

  alert(text);
}

// This functions will alert the numbers

function sumClick() {
  alert("The sum of your numbers is: " + sum);
}

function avgClick() {
  alert("The average of your numbers is: " + avg);
}

function minClick() {
  alert("The smaller number is: " + min);
}

function maxClick() {
  alert("The greater number is: " + max);
}

function lowHigh() {
  var list, i, switching, b, shouldSwitch;
  list = document.getElementById("list");
  switching = true;
  /* Make a loop that will continue until
  no switching has been done: */
  while (switching) {
    // Start by saying: no switching is done:
    switching = false;
    b = list.getElementsByTagName("li");
 
    // Loop through all list items:
    for (i = 0; i < (b.length - 1); i++) {
      // Start by saying there should be no switching:
      shouldSwitch = false;
      /* Check if the next item should
      switch place with the current item: */
      if (b[i].innerText > b[i + 1].innerText) {
        shouldSwitch = true;
        break;
      }
    }
    if (shouldSwitch) {
      /* If a switch has been marked, make the switch
      and mark the switch as done: */
      b[i].parentNode.insertBefore(b[i + 1], b[i]);
      switching = true;
    }
  }


}

// Here we add all events

input.addEventListener("input", enableDisable);
add.addEventListener("click", addClick);
document.getElementById("avg").addEventListener("click", avgClick);
document.getElementById("sum").addEventListener("click", sumClick);
document.getElementById("min").addEventListener("click", minClick);
document.getElementById("max").addEventListener("click", maxClick);
document.getElementById("frequency").addEventListener("click", frequencyClick);
    
    
  </script>   


</body>
  

  
  
</html>

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

1 Comment

The code has still a little problem and the answer isn't completely correct I will adapt that tomorrow. sorry.

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.