问题
Whilst this does use some of the code from a question I asked yesterday (Dynamically check / uncheck checkboxes in a tree), I feel that this is a slightly different question as I need to add in clearing divs
and also slide data in the tree up and down.
I've taken what I learnt yesterday and added in a slider as per this link - http://jsfiddle.net/3V4hg/ - but now I've added clearing divs
the tree is not unchecking all the way to the top if the bottom of the tree has no options selected. If you look at the JSFiddle, if you check A and/or B then uncheck it, the parent and grandparent do not uncheck automatically. Also, for some reason that I haven't figured out yet - the slider decides to slide upon clicking the checkbox in the child area (I've also noticed that the toggle image for the region area to display changes when the continent one toggles - haven't tried to solve that as just noticed when adding to JSFiddle).
I'm also thinking that there may be a better way to code the togglers/sliders (since used by more than one kind of toggle, but I'm unsure).
回答1:
Fiddle: http://jsfiddle.net/3V4hg/2/
I have applied some modifications to your code. Have a look at the fiddle and comments (at the code, and at the bottom of the answer):
$('#delivery_zones :checkbox').change(function(){
$(this).siblings('ul').find(':checkbox').prop('checked', this.checked);
if(this.checked){
$(this).parentsUntil('#delivery_zones', 'ul').siblings(':checkbox').prop('checked', true);
} else {
$(this).parentsUntil('#delivery_zones', 'ul').each(function() {
var $this = $(this);
var childSelected = $this.find(':checkbox:checked').length;
if(!childSelected){
// Using `prevAll` and `:first` to get the closest previous checkbox
$this.prevAll(':checkbox:first').prop('checked', false);
}
});
}
});
// collapse countries and counties onload
$(".country_wrap").hide();
$(".county_wrap").hide();
// Merged two click handlers
$("#delivery_zones").click(function(event){
var root = event.target; // Get the target of the element
if($.nodeName(root, 'input')) return; // Ignore input
else if(!$.nodeName(root, 'li')) {
root = $(root).parents('li').eq(0); // Get closest <li>
}
// Define references to <img>
var img = $('.toggle img', root).eq(0);
// Define reference to one of the wrap elements *
var c_wrap = $('.country_wrap, .county_wrap', root).eq(0);
if(img.attr('src') == "http://uk.primadonna.eu/images/arrow_white_up.gif"){
img.attr('src', 'http://www.prbuzzer.com/images/downarrow-white.png');
c_wrap.slideUp("slow");
} else {
img.attr('src', 'http://uk.primadonna.eu/images/arrow_white_up.gif');
c_wrap.slideDown("slow");
}
});
* I have defined the root to be a <li>
element. The first occurrence of the .count(r)y_wrap
element should be selected, which is achieved using .eq(0)
.
Your previous code contained some logical errors, which I have also fixed: $('.toggle img', this)
selects every <img>
element which is a child of .toggle
, which caused the arrows at the end of the tree to toggle too. My solution using event.target
is more neater, and allows your example to be extended to even deeper trees.
来源:https://stackoverflow.com/questions/7965531/check-uncheck-tree-with-toggle-slide-few-minor-coding-issues