views:

1844

answers:

3

Hi all, Can you do a better code? I need to check/uncheck all childs according to parent and when an child is checked, check parent, when all childs are unchecked uncheck parent.

    $(".parent").children("input").click(function() {
    $(this).parent().siblings("input").attr("checked", this.checked);
});

$(".parent").siblings("input").click(function() {
    if (this.checked) {
        $(this).siblings("div").children("input").attr("checked", true);
        return;
    }

    var childs = $(this).siblings("div").siblings("input");

    for (i = 0; i < childs.length; i++) {
        if ($(childs.get(i)).attr("checked"))
            return;
    }

    $(this).parent().children("div").children("input").attr("checked", false);
});
+1  A: 
$(".parent").children("input").click(function() {
    $(this).parent().siblings("input").attr("checked", this.checked);
});

$(".parent").siblings("input").click(function() {
    $(this).siblings("div").children("input").attr("checked",
        this.checked || $(this).siblings("input[checked]").length>0
    );
});
Hafthor
what's the point of doing ".siblings(...).siblings(...)"? Also: "$(this).parent().children(...)" could just be ".siblings(...)"
nickf
nickf: guh, to see if you were paying attention :) - actually, i just copied that from Zote's code (var childs line) - i've cleaned it up more (+1)
Hafthor
+1  A: 

woah, i'm mega confused. it looks as though you have inputs with other inputs inside of them? ...which doesn't make sense. Here's what I think your structure looks like, so here I go.

<div class="parent">
    <input type="checkbox" />
    <div>
        <input type="checkbox" />
        <input type="checkbox" />
    </div>
    <input type="checkbox" />
    <div>
        <input type="checkbox" />
        <input type="checkbox" />
    </div>
</div>

And here's the code I'd use.

$("input[type='checkbox']").click(function() {
    // turn on or off all descendants.
    $(this)         // get this checkbox
        // get the div directly after it
        .next('div')
        // get ALL the inputs in that div (not just first level children)
        .find("input[type='checkbox']")
        .attr("checked", this.checked)
    ;

    // now check if we have to turn the parent on or off.
    $(this)
        .parent()  // this will be the div
        .prev('input[type="checkbox"]')  // this is the input
        .attr(
            "checked",     // set checked to true if...
            this.checked   // this one is checked, or...
            || $(this).siblings("input[type='checkbox'][checked]").length > 0
                           // any of the siblings are checked.
        )
    ;
});

update: i've just tested this and it totally works (woo!). It also works with as many levels of nesting as you want, not just two.

nickf
A: 

Hello, new to Stack.

This is a lovely little thread that has got me nearly where I need to be. I've slightly adapted Nickf's code. The aim is that checking a child would also check the parent, and unchecking a parent would also uncheck all children.

$("input[type='checkbox']").click(function() { if (!$(this.checked)) {

$(this) 
    .next('div')
    .find("input[type='checkbox']")
    .attr("checked", this.checked)
;
}


$(this)
    .parent()  
    .prev('input[type="checkbox"]')  
    .attr("checked", this.checked || $(this).siblings("input[type='checkbox'][checked]").length > 0

    )
;

});

How would one go about tweaking this so that all descendants are unchecked if the parent is unchecked?

New all things JQ and javascript..apologies.

bulkhead