Mico
Mico

Reputation: 497

jquery check checkboxes within an element only

I have these audience groups with audiences hidden under it. When a user clicks on the audience group name, the hidden audiences will appear. now, what i want to do is when a user clicks on the audience group checkbox, only the audience checkboxes under it will be checked also.

currently i have the following, but with a little bug, when i clicked on an audience group checkbox, all the audience checkbox, even those not under is also checked. i want only those audience under that audience group will be checked.

you can see more of my code here: http://jsfiddle.net/CVnTy/

i have this example html:

<div class='audience-group'>
    <input type='checkbox' class='audience-group-checkbox' value='9' />
    <div class='audience-group-name'>
        JGG Enterprises
    </div>
    <div class='audience'>
        <input type='checkbox' class='audience-checkbox' value='7' />
        <div class='audience-name'>
            Mucho, George
        </div>
    </div>
    <div class='audience'>
        <input type='checkbox' class='audience-checkbox' value='9' />
        <div class='audience-name'>
            Bo, Jen
        </div>
    </div>
    <div class='audience'>
        <input type='checkbox' class='audience-checkbox' value='10' />
        <div class='audience-name'>
            Gin, Junto
        </div>
    </div>
    <div class='audience'>
        <input type='checkbox' class='audience-checkbox' value='12' />
        <div class='audience-name'>
            Molina, Greg
        </div>
    </div>
    <div class='audience'>
        <input type='checkbox' class='audience-checkbox' value='36' />
        <div class='audience-name'>
            Berkely, Dada
        </div>
    </div>
</div>
</div>
<div>
    <div class='audience-group'>
        <input type='checkbox' class='audience-group-checkbox' value='8' />
        <div class='audience-group-name'>
            GBA Inc.
        </div>
        <div class='audience'>
            <input type='checkbox' class='audience-checkbox' value='1' />
            <div class='audience-name'>
                Kapate, Jones
            </div>
        </div>
        <div class='audience'>
            <input type='checkbox' class='audience-checkbox' value='2' />
            <div class='audience-name'>
                Bingo, Gringo
            </div>
        </div>
        <div class='audience'>
            <input type='checkbox' class='audience-checkbox' value='4' />
            <div class='audience-name'>
                Doe, John
            </div>
        </div>
        <div class='audience'>
            <input type='checkbox' class='audience-checkbox' value='8' />
            <div class='audience-name'>
                Merio, Horhe
            </div>
        </div>
        <div class='audience'>
            <input type='checkbox' class='audience-checkbox' value='35' />
            <div class='audience-name'>
                Dalisay, JM
            </div>
        </div>
    </div>
</div>

and my jquery code:

$('.audience-group-name').click(function() {
    if ($(this).nextUntil('.audience-group').length) {
        $(this).nextUntil('.audience-group').toggle();
    } else {
        alert('No audience under this group.');
    }
});

$('.audience-group-checkbox').each(function() {
    $(this).click(function() {
        $('.audience-checkbox').attr('checked', $(this).is(':checked'));
    });
});

i'm kinda new to jquery, thanks for any help! :)

Upvotes: 0

Views: 443

Answers (6)

Ilia G
Ilia G

Reputation: 10221

Well, you already had the code fro expand/collapse. All you need is to extend it a bit like so. I also took the liberty of simplifying your code a bit.

Upvotes: 1

DanyZift
DanyZift

Reputation: 687

you don't need to use an each for assigning your click event. If you just replace that with:

$('.audience-checkbox').click(function(){
   $(this).attr('checked', true);
})

Upvotes: -1

James Allardice
James Allardice

Reputation: 166031

Instead of the each loop you're currently using, you can use something like this instead:

$('.audience-group-checkbox').click(function() {
    $(this).closest(".audience-group").find(".audience-checkbox").prop("checked", this.checked); 
});

This gets the ancestor .audience-group element (closest - parent would also work here, if your HTML will always be as shown in the question), then gets all descendant elements with class "audience-checkbox" (find). Note that I've also used prop instead of attr, since checked is a DOM property. I've also used this.checked rather than wrapping this in another jQuery object, simply because it's shorter and faster to access the property on the DOM element itself.

Here's an updated fiddle.

Note that you don't need the each. The majority of jQuery methods apply to all elements in the matched set, and click (and all event handler methods for that matter) is no exception.

Upvotes: 2

Jasper
Jasper

Reputation: 76003

//add event handler to all '.audience-group-checkbox' elements
$('.audience-group-checkbox').click(function() {

    //cache this element
    var $this = $(this);

    //select the parent of this object and then find all the '.audience-checkbox' elements under it
    $this.parent().find('.audience-checkbox').prop('checked', $this.is(':checked'));
});

Here is a jsfiddle: http://jsfiddle.net/k57Tp/

Upvotes: 0

devnull69
devnull69

Reputation: 16574

$('.audience-group-checkbox').click(function() {
    $(this).find('.audience-checkbox').prop('checked', $(this).is(':checked'));
})

Upvotes: 0

T. Stone
T. Stone

Reputation: 19495

In this code:

$('.audience-group-checkbox').each(function() {
    $(this).click(function() {
        $('.audience-checkbox').attr('checked', $(this).is(':checked'));
    });
});

$('.audience-checkbox') will re-select all elements that have class audience-checkbox.

What you probably want to do is only change the attribute for the item that was clicked, correct?

That would be...

$('.audience-group-checkbox').each(function() {
    $(this).click(function() {
        $(this).attr('checked', $(this).is(':checked'));
    });
});

By the way, when you do this kind of thing, be aware that some browsers will do this behavior by default, so you'll end up with a situation where some browsers will work like you expect, and others will check the box twice (the first time changing it and the 2nd tome changing it back). I've found unless you have a really good reason for doing so, you should just let the browser handle checking and unchecking.

It's possible to prevent the browser default with something like...

.click(function (e) { e.preventDefault(); })

Upvotes: 1

Related Questions