0

I have been trying to create checkboxes and show their values. When you try to select only one of them, it works. When you try to select more than one, it only shows the highest value selected. I want to do this only with javascript, no jquery. How can I show all the values of all selected checkboxes?

Here is the code so far:

Html:

<!doctype html>
<html>
    <head>
        <title>Javascript checkboxes in real time</title>
        <link rel = "stylesheet" href = "css/default.css">
    </head>
    <body>
        <form action = "" method = "post">
            <input type="checkbox" id = "1" value = "1">1<br>
            <input type="checkbox" id = "2" value = "2">2<br>
            <input type="checkbox" id = "3" value = "3">3<br>
            <input type="checkbox" id = "4" value = "4">4<br>
            <input type="checkbox" id = "5" value = "5">5<br>
        </form>
        <section></section>
        <script src = "js/default.js"></script>
    </body>
</html>

Javascript:

var checkbox = document.getElementsByTagName('input');
var section = document.getElementsByTagName('section');

setInterval(function(){
    for(var i = 0; i <= checkbox.length - 1; i++){
        if(checkbox[i].checked){
            section[0].innerHTML = checkbox[i].value;
            break;
        }
        else{
            section[0].innerHTML = null;
        }
    }
}, 10);

2 Answers 2

1

There are several things wrong about your code, you are endlessly querying the DOM every 10ms for no good reason. DOM elements fire events when things happen to them.

var section = document.getElementsByTagName('section')[0];
var inputs = document.getElementsByTagName('input');

// Document was changed!
document.addEventListener('change', function(event) {
  // Specifically, an input was changed in the document!
  if (event.target.tagName === 'INPUT') {
    // Update the section
    updateCheckboxStatus(section);
  }
});

// This function updates an element with the input status
function updateCheckboxStatus(element) {
  // Clear the element first
  element.textContent = '';
  // Loop through each of the inputs
  [].forEach.call(inputs, function(input) {
    // If checked, add to the element
    if (input.checked) { element.textContent += input.value + " "; }
  });
}
<form action="" method="post">
  <input type="checkbox" id="1" value="1">1
  <br>
  <input type="checkbox" id="2" value="2">2
  <br>
  <input type="checkbox" id="3" value="3">3
  <br>
  <input type="checkbox" id="4" value="4">4
  <br>
  <input type="checkbox" id="5" value="5">5
  <br>
</form>
<section></section>

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

1 Comment

Accepted answer coming. Btw, your solution is very wise and clear.
0

EDIT: I'm posting the minimal change I found to fix your issue. This is by no means the right approach to the task at hand - as explained perfectly at the (now) accepted answer. This code should serve just so you'll see the diff from your code.

Also - please don't use setInterval (use setTimeout instead and renew it each time from inside the callback):

var checkbox = document.getElementsByTagName('input');
var section = document.getElementsByTagName('section');

setInterval(function(){
   section[0].innerHTML = '';
   for(var i = 0; i < checkbox.length; i++){
     if(checkbox[i].checked){
       section[0].innerHTML += checkbox[i].value;        
     }
   }
 }, 10);

6 Comments

"Please don't use setInterval" and yet you're using it, like everyone else, for no reason at all.
Problem is that if I used setTimeout it would only happen once. Also I think the above answer, using event listeners is better. @Second I believe Doron wanted to show me how it works with the logic I was using. That is the reason why he used setInterval.
@GSquadron What he means by using setTimeout is to use that, and inside the setTimeout call the next setTimeout (so every iteration is calling the next iteration on its own)
There is a reason - and you're welcome to ask before downvoting. I wanted to do the minimal change to help him see his mistake. I figured it will serve him better that way - than to completely change the code. When someone asks a specific question I try to provide a specific answer and not add "noise" that might confuse.
@DoronZavelevsky That is true, but in this case the entire approach is wrong. setInterval (or setTimeout, for this matter) is the wrong tool for the job. Observing changes in DOM is a solved problem ;)
|

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.