最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Dynamically checkuncheck checkboxes in a tree - Stack Overflow

programmeradmin11浏览0评论

I have a similar question to Uncheck parent node if all children unchecked in JQuery (with this solution) and have tried to modify it so that the children will also all uncheck if the parent is unchecked (which the above/below fails to do).

JSFiddle for the above (/)

jQuery.each(jQuery('#treeList ul li').find(':checkbox'),  function(){
    jQuery(this).change(function (){
        if (jQuery(this).is(':checked')) {
                      jQuery(this).parentsUntil('#treeList').siblings().filter('input:checkbox').attr('checked', true).trigger('change');
        }else{

            jQuery(this).parents('ul:first').siblings('input:checkbox').prop('checked', $(this).parent().siblings().children('input:checked').length).trigger('change');
        }        
    });    
});

Though I'm not sure why, but I had to change prop from the last line to attr in order for it to correctly work as JSFiddle locally for some reason...

Basically I have a 3 level setup:

Grand-Parent
- Parent
-- Child
  • If the grandparent is checked/unchecked, then its children and grandchildren should all be checked/unchecked too.
  • If the parent is checked/unchecked, its children should be checked/unchecked as well as its parent.
  • If the children are checked, then its parent and grandparent should be checked (if no children are checked then parent shouldn't be checked).

I'm trying to change this to Continent, Country, Region - I think you will understand if I were to just say this....

Thanks

I have a similar question to Uncheck parent node if all children unchecked in JQuery (with this solution) and have tried to modify it so that the children will also all uncheck if the parent is unchecked (which the above/below fails to do).

JSFiddle for the above (http://jsfiddle/fRxVs/)

jQuery.each(jQuery('#treeList ul li').find(':checkbox'),  function(){
    jQuery(this).change(function (){
        if (jQuery(this).is(':checked')) {
                      jQuery(this).parentsUntil('#treeList').siblings().filter('input:checkbox').attr('checked', true).trigger('change');
        }else{

            jQuery(this).parents('ul:first').siblings('input:checkbox').prop('checked', $(this).parent().siblings().children('input:checked').length).trigger('change');
        }        
    });    
});

Though I'm not sure why, but I had to change prop from the last line to attr in order for it to correctly work as JSFiddle locally for some reason...

Basically I have a 3 level setup:

Grand-Parent
- Parent
-- Child
  • If the grandparent is checked/unchecked, then its children and grandchildren should all be checked/unchecked too.
  • If the parent is checked/unchecked, its children should be checked/unchecked as well as its parent.
  • If the children are checked, then its parent and grandparent should be checked (if no children are checked then parent shouldn't be checked).

I'm trying to change this to Continent, Country, Region - I think you will understand if I were to just say this....

Thanks

Share Improve this question edited May 23, 2017 at 11:58 CommunityBot 11 silver badge asked Oct 31, 2011 at 14:26 MrJMrJ 1,9382 gold badges17 silver badges30 bronze badges 4
  • Have a look at this question on Code Review codereview.stackexchange./questions/4939/… – John Hartsock Commented Oct 31, 2011 at 14:35
  • Just took a look at that, and tried the JSFiddle for it - but that only makes the child's parent check if both (I imagine it ends up being all) children have been checked - I'd like it so that just one child feeds up the tree. – MrJ Commented Oct 31, 2011 at 14:38
  • I'm having a look at it. I've just optimized the code, moving onwards to fixing it ;) – Rob W Commented Oct 31, 2011 at 14:41
  • Thanks @RobW! Look forward to seeing your solution, hope I can increase my understanding of jQuery through it :) – MrJ Commented Oct 31, 2011 at 14:43
Add a ment  | 

2 Answers 2

Reset to default 6

Here's the solution: Fiddle: http://jsfiddle/fRxVs/55/

$('#treeList :checkbox').change(function (){
    $(this).siblings('ul').find(':checkbox').prop('checked', this.checked);
    if (this.checked) {
        $(this).parentsUntil('#treeList', 'ul').siblings(':checkbox').prop('checked', true);
    } else {
        $(this).parentsUntil('#treeList', 'ul').each(function(){
            var $this = $(this);
            var childSelected = $this.find(':checkbox:checked').length;
            if (!childSelected) {
                $this.prev(':checkbox').prop('checked', false);
            }
        });
    }
});

Modifications and explanations

  • $ is exactely the same as jQuery. Be consistent when using it: jQuery should only be used when you're not sure whether $ === jQuery (is $ overwritten?).
  • :checkbox is a selector which matches every input[type="checkbox"]. It's obsolete to specify input:checbkox, since a checkbox element is always an input element.
  • .find(..) seeks for any element which is a child (not necessery the direct child) of the matched selector. "#treeList :checkbox" is faster, and has the equivalent result as $('#treeList').find(':checkbox').
  • When a property/method/event is added to a jQuery object, all elements which match the selector will be modified. Therefore, you don't have to loop through each element individually: jQuery.each(jQuery('#treeList :checkbox'), function(){ jQuery(this).change(...)}) can be shortened to jQuery('#treeList :checkbox').change(...).
  • You don't have to trigger change after changing a checkbox check state, because the function already takes care of the full tree.

Old question but you could just do it like this:

$('input[type=checkbox]').change(function(){
    $(this).next().find('input[type=checkbox]').prop('checked', this.checked);
    $(this).parents('ul').prev('input[type=checkbox]').prop('checked', function(){
        return $(this).next().find(':checked').length;
    });
});

Fiddle: http://jsfiddle/ojc1qg1f/

发布评论

评论列表(0)

  1. 暂无评论