简体   繁体   中英

Jquery Check parent checkboxes in nested ul li

I have a script that will check and uncheck all children checkboxes in a nested list. I am now trying to get it so I can check a low level checkbox and it will check all the parents only back up to the highest level. Here is a JSFiddle

<ul class="tree" id="tree">

    <li><input type="checkbox" name="account_settings" value="yes">Account Settings <!-- AND SHOULD CHECK HERE -->
        <ul>
            <li><input type="checkbox" name="one" value="one">AS One</li>
            <li><input type="checkbox" name="two" value="two">AS Two</li>
            <li><input type="checkbox" name="user_roles" value="user_roles">Users &amp; Roles <!-- SHOULD CHECK HERE -->
                <ul>
                    <li><input type="checkbox" name="user_role" value="add">Add</li>
                    <li><input type="checkbox" name="user_role" value="delete">Delete</li> <!-- CHECK HERE -->
                </ul>
            </li>
        </ul>
    </li>

    <li><input type="checkbox" name="rl_module" value="yes">RL Module</li>

    <li><input type="checkbox" name="rl_module" value="yes">Accounting
        <ul>
            <li><input type="checkbox" name="vat" value="yes">VAT</li>
            <li><input type="checkbox" name="bank_account" value="yes">Banking
                <ul>
                    <li><input type="checkbox" name="view" value="yes">View</li>
                    <li><input type="checkbox" name="crud" value="yes">CRUD</li>
                </ul>
            </li>
        </ul>
    </li>

</ul>

And the corresponding javascript:

$('input[type=checkbox]').click(function(){

    // if is checked
    if($(this).is(':checked')){

        // check all children
        $(this).parent().find('li input[type=checkbox]').prop('checked', true);

        // check all parents
        $(this).parent().prev().prop('checked', true);

    } else {

        // uncheck all children
        $(this).parent().find('li input[type=checkbox]').prop('checked', false);

    }

});

It looks like you want something like this

$('input[type=checkbox]').click(function(){
    if(this.checked){ // if checked - check all parent checkboxes
        $(this).parents('li').children('input[type=checkbox]').prop('checked',true);
    }
    // children checkboxes depend on current checkbox
    $(this).parent().find('input[type=checkbox]').prop('checked',this.checked); 
});

FIDDLE

If you want to check up and down hierarchy - you can do it like this

$('input[type=checkbox]').click(function(){
    // children checkboxes depend on current checkbox
    $(this).next().find('input[type=checkbox]').prop('checked',this.checked);
    // go up the hierarchy - and check/uncheck depending on number of children checked/unchecked
    $(this).parents('ul').prev('input[type=checkbox]').prop('checked',function(){
        return $(this).next().find(':checked').length;
    });
});

FIDDLE

This should do it:

$('input[type=checkbox]').click(function () {
    $(this).parent().find('li input[type=checkbox]').prop('checked', $(this).is(':checked'));
    var sibs = false;
    $(this).closest('ul').children('li').each(function () {
        if($('input[type=checkbox]', this).is(':checked')) sibs=true;
    })
    $(this).parents('ul').prev().prop('checked', sibs);
});

jsFiddle example

Latest update handles up and down the hierarchy, and siblings.

Just use jquery.parents() . It is somewhat similar to find() except it searches all parents. Something like this might be close to what you are looking for:

$(this).parents('li').each(function() {
  $(this).children('input').prop('checked', true);
});

See http://api.jquery.com/parents/ for more information.

EDIT: Alright, here is a solution that works:

http://jsfiddle.net/3y3Pb/12/

EDIT2: And a more streamlined solution here:

http://jsfiddle.net/3y3Pb/14/

Have a JSFiddle: http://jsfiddle.net/3y3Pb/16/

I would recommend adding a parent attribute to the checkboxes. This parent attribute will reference the parent checkbox's id so that you don't have to worry about your structure changing:

$('input type=[checkbox]').change(function () {
    $('#' + $(this).attr('parent')).prop('checked', this.checked);
});

Ex:

<input type="checkbox" name="account_settings" value="yes" id="as">Account Settings
    <ul>
        <li><input type="checkbox" name="one" value="one" parent="as" id="one">AS One</li>

You can use prevAll() also I have the same issue. In my case there are multiple checkboxes in li with labels, and each checkbox above target have class parent (generated in js)

$(this).parents().prevAll('input:checkbox.parent').each(function () {
                       $(this).attr('checked', true);
                   });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM