0

In my HTML document, I want to have 9 checkboxes. When a checkbox is selected, I want a corresponding block of text to show. I'm trying to create a single function for this, that uses a parameter to select the corresponding box, but I've been unsuccesfull so far. I'm not experienced with HTML of jQuery at all, so I've got no idea what the problem is.

The code I currently have is as follows:

$(document).ready(function() {
    for ($i = 0; $i < 9; $i++) {
        $("input[name=checkbox" + $i + "]").click(function () {
            $('#box' + $i).toggle();
        });
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" name="checkbox1" value="alpha"> Checkbox 1 <br>
<input type="checkbox" name="checkbox2" value="beta"> Checkbox 2 <br>

<div id = "box1" style="display:none">Checkbox 1 is selected</div>
<div id = "box2" style="display:none">Checkbox 2 is selected</div>

Can anyone please help me understand why the .toggle doesn't work correctly?

Tyler Roper
  • 21,445
  • 6
  • 33
  • 56
RBS
  • 105
  • 6

5 Answers5

0
$(document).ready(function() {
$("input[type='checkbox']").click(function(){
  alert("Checkbox "+$(this).index()+" is selected!");
 });
});

It is not viable to use for loop like that. Use "this" selector to fetch current clicked checkbox with click function applied on all checkboxes.

UPDATE You are applying for loop to 9 checkboxes which means you are adding similar code 9 times in your DOM which is not necessary. If you don't want them to function for other checkboxes then apply a class to desired checkboxes and access by class. index(".checkbox_class") will give you the index of checkbox from checkboxes of class only. It will not count <br> tags in between :)

 $(document).ready(function() {
    $(".checkbox_class").click(function(){
      alert("Checkbox "+$(this).index(".checkbox_class")+" is selected!");
     });
    });
Ninad Ramade
  • 256
  • 2
  • 9
  • Please correct me if I'm wrong, but the for does seem to work (if I change the toggle to a fixed id). I just put the "Checkbox X is selected" there as a placeholder, since the actual text that needs to be displayed is very large. Furthermore, on the HTML page this has to work on there are several other groups of checkboxes that do not need to have this to function for them. – RBS Jul 07 '17 at 13:50
  • You are applying for loop to 9 checkboxes which means you are adding similar code 9 times in your DOM which is not necessary. The same thing can be done by using the method in my answer. If you dont want them to function for other checkboxes then apply a class to desired checkboxes. – Ninad Ramade Jul 07 '17 at 13:52
  • The issue with this solution is that the `
    ` elements are included when using `.index()`, therefore the second checkbox would have an index of `3`, the third checkbox would have an index of `5`, etc.
    – Tyler Roper Jul 07 '17 at 13:55
  • Okay, I have edited the answer for your solution. just use a parameter of index(). – Ninad Ramade Jul 07 '17 at 14:06
0

Because of how variable scoping works in for loops, your toggle is actually targeting #box9, as that was the last value of $i. Luckily in this case, there's really no need for a loop at all.

We can apply the handler to all checkboxes by using a Starts With Selector (^=). From there, we can get the number of the clicked checkbox by grabbing it's name and removing the word "checkbox" from it.

Then we can simply append that number to "#box" to select the corresponding element to toggle.

$("input[name^=checkbox]").click(function () {
    //$(this) refers to the checkbox that was clicked
    var num = $(this).attr("name").replace("checkbox","");
    var $box = $("#box" + num);
    $box.toggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" name="checkbox1" value="alpha"> Checkbox 1 <br>
<input type="checkbox" name="checkbox2" value="beta"> Checkbox 2 <br>

<div id = "box1" style="display:none">Checkbox 1 is selected</div>
<div id = "box2" style="display:none">Checkbox 2 is selected</div>

If you have other checkboxes with name="checkboxX" that you don't want this to apply to...

...you'll need to separate them into groups, most easily done just by applying a class to the ones you want.

<input type="checkbox" name="checkbox1" class="clickable" />
<input type="checkbox" name="checkbox2" class="clickable" />
<input type="checkbox" name="checkbox3" />

Then simply replace the selector in the code provided above to target only those with the class clickable:

$("input[type=checkbox].clickable").click(function () {
    //...
});

In this example, checkbox3 would not trigger the event because it doesn't have the class applied.

Tyler Roper
  • 21,445
  • 6
  • 33
  • 56
0

What you are looking for is jQuery this, which can be used to get the current element clicked on. Say all the checkboxes have the class "checkbox". All the boxes have the class "box". You can use .index() to get the index of the .checkbox clicked on, and find the .box with the same index. Then all you have to do is .toggle() it.

$('.checkbox').click(function() {
  var index_number = $('.checkbox').index(this);
  $('.box').eq(index_number).toggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<input type="checkbox" class="checkbox"> Checkbox 1<br>
<input type="checkbox" class="checkbox"> Checkbox 2<br>

<div style="display:none" class="box">Checkbox 1 is selected</div>
<div style="display:none" class="box">Checkbox 2 is selected</div>
James Douglas
  • 3,328
  • 2
  • 22
  • 43
  • *"You need to give checkbox 1 a class (alpha in this example) and give one of the boxes the same class."* - While I feel the need to point out that he doesn't "*need"* to do any of that, I'd also like to mention that this is incredibly strange implementation. Applying the same class to both the input and the div is questionable, especially considering that it requires a new unique class for each and every checkbox. If he has 9 checkboxes, as he explains, he'll need 9 unique classes? I think there are better methods. – Tyler Roper Jul 07 '17 at 14:11
  • @Santi Ok, I'll try and find a more reasonable/better way of doing it. Thanks for the feedback! – James Douglas Jul 07 '17 at 14:12
  • No problem, I appreciate you being open to the criticism. Your example isn't *wrong*, however I think it went a little bit off the tracks from OP's example, being that it requires him to drastically change his markup. Good luck! – Tyler Roper Jul 07 '17 at 14:13
  • 1
    @Santi How does it look now? – James Douglas Jul 07 '17 at 14:26
  • Though it still has modified markup (the id's/names example from OP's question has changed to classes), this answer is much better! – Tyler Roper Jul 07 '17 at 14:30
0

I'm not exactly sure what the problem is. In jQuery .each() is built in and is better than the for loop, so lets use that.

$(document).ready(function() {
  $("input[type=checkbox]").each(function(index) {
    $("input[name=checkbox" + (index + 1) + "]").click(function() {
      $("#box" + (index + 1)).toggle()
    })
  })
}); 

So let's start at the top first we are selecting all the inputs that have a type of checkbox and executing a function for each matched element, it also gives us some data the "index" being passed through starting at 0 and going up.

We then grab all matched elements that are inputs with the name of checkbox and the number after checkbox is going to start at 1 and finish at 2 since we are adding 1 to the index. When you click on one of these inputs we will call a new function that selects the box with the correct number (again using the index + 1, so we're not starting at 0) and toggles it.

cuppajoeman
  • 252
  • 5
  • 13
0

The problem with the I condition in For is because there is no comparision value. The easiest way for it to determine how much you have is by making an array:

var
   id = ['box1', 'box2'], //repeat til you get to 9
   checkbox = ['checkbox1', 'checkbox2'], //repeat til you get to 9
   frame = ""
;


for (i = 0; i < id.length; i++){
   frame +=
       "<div id=' " + box[i] + " '>"+
       checkbox[i] + "is selected</div>"
   ;
}

document.getElementById('demo').innerHTML = frame;

Then your seperate script file (because it wont work in the same file!!!)

//your toggle events here
$('#alpha').toggle(function{
     $('#box1').show(0);
     $('#box2, #box3, #box4, #box5, #box6, #box7, #box8, #box9').hide(0);
});
//repeat til you get to 9

My cloning result experience comes from the fiddle: https://fiddle.jshell.net/NitroXAce/d1qro5g3/15/

Because I tried to make panels that do certain things but kept a 'template'. In your example, you simply needed to clone your inputs and your display none divs. Happy hunting!

Gareth Compton
  • 159
  • 1
  • 12