2

I have a form with a checkbox (contained within a label #contact). For the change action of this checkbox, I am showing/hiding a div (#options).

To ensure that if the checkbox is checked the #options div always is always shown (and avoid the situation where checking the checkbox actually hides the subjequent options), I am using this code:

$('#contact :checkbox').is(':checked') ? $("#options").show() : $("#options").hide();

This works fine. The problem I have is that instead of a single checkbox with an ID, I want to have multiple checkboxes. I want to show/hide the next instance of my .hidden class based on whether the previous checkbox (within a label with the class .trigger) is checked or not. I have tried this:

$(document).ready(function() {
    if( $('.trigger :checkbox').is(':checked') ) {
        $(this).parent().nextAll('ul.hidden').show();
    } else {
        $(this).parent().nextAll('ul.hidden').hide();
    }
});

But to no avail. The checkboxes are in an unordered list, like this:

<ul>
  <li><label class="trigger"><input type="checkbox" name="02" /> Trigger 1</label>
      <ul class="hidden">
        <li><label><input type="checkbox" name="02-sub1" /> Normal</label></li>
        <li><label><input type="checkbox" name="02-sub2" /> Normal</label></li>
      </ul>
  </li>
  <li><label><input type="checkbox" name="02" /> Normal</label></li>
  <li><label><input type="checkbox" name="03" /> Normal</label></li>
  <li><label class="trigger"><input type="checkbox" name="04" /> Trigger 2</label>
      <ul class="hidden">
        <li><label><input type="checkbox" name="04-sub1" /> Normal</label></li>
        <li><label><input type="checkbox" name="04-sub2" /> Normal</label></li>
      </ul>
  </li>
</ul>

I can't see where I'm going wrong here; presumably my selector is incorrect, but I've played around with the syntax for ages and not got anywhere. Thanks in advance (and thank you for reading this far).

1

2 Answers 2

4

You need to run your code inside a change handler, so this refers to the checkbox you want, like this:

$(document).ready(function() {
   $('.trigger :checkbox').change(function() {
     if( $(this).is(':checked') ) {
       $(this).parent().nextAll('ul.hidden').show();
     } else {
       $(this).parent().nextAll('ul.hidden').hide();
     }
   });
});

...and that can be made much shorter with .toggle(bool), like this:

$(function() {
   $('.trigger :checkbox').change(function() {
     $(this).parent().nextAll('ul.hidden').toggle(this.checked);
   });
});

If you need it to run when the page loads, so the show/hide states match the checkbox, just call that change handler with .change() (shortcut for .trigger('change')), like this:

$(function() {
   $('.trigger :checkbox').change(function() {
     $(this).parent().nextAll('ul.hidden').toggle(this.checked);
   }).change();
});
Sign up to request clarification or add additional context in comments.

3 Comments

Do you know how I can incorporate your function above (thank you by the way, it answers my initial question perfectly) with my current change function? I am having real problems getting them both to work.
@EdM - Honestly, I'd roll the question back to the original so it's a better resource, and ask your new/heavily modified question separately...as it stands an edit like this after answers are posted makes the question make very little sense to those finding it later. Can you post a separate question and link it here, to keeps things a bit cleaner?
Ok, that sounds like a good idea thank you. Quite new to the site so it's useful to know the best way to go about things.
0

You know you can roll your own fields, right? The typical way to do that is with a "rel=" field that has no meaning in HTML but can be picked up and used in jquery.

if ($('#contact :checkbox').is(':checked')) {
    $("#" + $('#contact :checkbox').attr('rel')).show();
} else {
    $("#" + $('#contact :checkbox').attr('rel')).hide();
}

And then:

  <li><label class="trigger"><input type="checkbox" name="04" rel="hidden-04" /> Trigger 2</label>
      <ul class="hidden" id="hidden-04">
        <li><label><input type="checkbox" name="04-sub1" /> Normal</label></li>
        <li><label><input type="checkbox" name="04-sub2" /> Normal</label></li>
      </ul>
  </li>

So then, when the checkbox named 04 is checked, we look in its rel field for the id of the object to hide() or show(). I think that's a LOT easier than trying to walk the dom to find the target object.

2 Comments

This wouldn't work correctly, since $('#contact :checkbox').attr('rel') would return the first match's rel attribute...and the selectors repeated many times. See my answer, doing this relatively is very easy :)
Hm. You're right--I was trying to work inside the code he had provided... The real solution (if you're going to do it this way; your post also solves his need) is to do this in the onClick handler bound to the :checkbox objects. Then you have a 'this' to talk about and you can get the rel attribute from that uniquely...

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.