Check the box

I have an AJAX request that inserts a list of folders with a checkbox next to each item in the list. If I check the box next to the parent folder, I will automatically check all the child folders by following these steps:

var checkChildCheckBoxes = function(){ var isAlreadyChecked = $(this).attr('isChecked'); if(isAlreadyChecked == 'true'){ $(this).parents(':eq(1)').find('.userPermissionCheckBox').each(function(){ $(this).prop('checked', false); }); $(this).attr('isChecked', 'false'); } else{ $(this).parents(':eq(1)').find('.userPermissionCheckBox').each(function(){ $(this).prop('checked', true); }); $(this).attr('isChecked', 'true'); } } 

It works great. What I'm trying to solve is if you do NOT have the parent element checked and you check the child element, it will automatically check the parent element.

I tried to do it wrong:

 if($(this).parent('ul').find('.userPermissionCheckBox:eq(0)').is('checked')){ } else{ $(this).parent('ul').find('.userPermissionCheckBox:eq(0)').prop('checked', true); } 

I didnโ€™t want to load this question with code, so I made a fiddle showing how the list is structured and how I use it. Go here: http://jsfiddle.net/BTXNk/1/ I kinda like n00b with Javascript, hope this question is not stupid. Thanks for taking the time to read it. http://jsfiddle.net/BTXNk/1/

+3
javascript jquery
source share
3 answers

I think this is a bit of a logical problem.

Suppose you have a parent, a child, and a child if you click on an unverified child, the current element is checked, and the child of this, as well as the parent of this flag, but the sibling of this is not checked correctly?

What happens when you click on a parent? None of the checkboxes selected? Therefore, if I decided to check all the checkboxes, but I already have a checkbox for the child, does this mean that I will need to check the parent checkbox to undo everything, and then click it again to check all the checkboxes?

This is not a good user experience. Anyway, I think it's best to separate the click events function from three different listeners, rather than trying to do this in one function. With this in mind, I did not write out a use case when everything is checked for you, and you canceled the check of one of the child elements, and then check the parent checkbox. You will have to continue to expand them.

 <ul class="level-one"> <li class="level-one-closed"> <span class="level-one-folder"> <input type="checkbox" class="userPermissionCheckBox-level-one" /> Parent </span> <ul class="level-two"> <li class="level-two-closed"> <span class="level-two-folder"> <input type="checkbox" class="userPermissionCheckBox-level-two" /> Child </span> <ul class="level-three"> <li> <span class="level-three-folder"> <input type="checkbox" class="userPermissionCheckBox-level-three" /> Child Child </span> </li> </ul> </li> <li class="level-two-closed"> <span class="level-two-folder"> <input type="checkbox" class="userPermissionCheckBox-level-two" /> Child </span> <ul class="level-three"> <li> <span class="level-three-folder"> <input type="checkbox" class="userPermissionCheckBox-level-three" /> Child Child </span> </li> <li> <span class="level-three-folder"> <input type="checkbox" class="userPermissionCheckBox-level-three" /> Child Child </span> </li> </ul> </li> </ul> </li> </ul> var $levelOneCheck = $('.userPermissionCheckBox-level-one'); var $levelTwoCheck = $('.userPermissionCheckBox-level-two'); var $levelThreeCheck = $('.userPermissionCheckBox-level-three'); $levelOneCheck.click(function() { var $isChecked = $(this).attr('isChecked'); if ($isChecked === 'true') { $(this).attr('isChecked', 'false'); $levelTwoCheck.prop('checked', false).attr('isChecked', 'false'); $levelThreeCheck.prop('checked', false).attr('isChecked', 'false'); } else { $(this).attr('isChecked', 'true'); $levelTwoCheck.prop('checked', true).attr('isChecked', 'true'); $levelThreeCheck.prop('checked', true).attr('isChecked', 'true'); } }); $levelTwoCheck.click(function() { var $isCheckedLevelTwo = $(this).attr('isChecked'); if ($isCheckedLevelTwo === 'true') { $(this).attr('isChecked', 'false'); $(this).closest('.level-one-closed').find('.level-one-folder .userPermissionCheckBox-level-one').prop('checked', false).attr('isChecked', 'false'); $(this).closest('.level-two-closed').find('.level-three-folder .userPermissionCheckBox-level-three').prop('checked', false).attr('isChecked', 'false'); } else { $(this).attr('isChecked', 'true'); $(this).closest('.level-one-closed').find('.level-one-folder .userPermissionCheckBox-level-one').prop('checked', true).attr('isChecked', 'true'); $(this).closest('.level-two-closed').find('.level-three-folder .userPermissionCheckBox-level-three').prop('checked', true).attr('isChecked', 'true'); } }); $levelThreeCheck.click(function() { var $isCheckedLevelTwo = $(this).attr('isChecked'); if ($isCheckedLevelTwo === 'true') { $(this).attr('isChecked', 'false'); $(this).closest('.level-one-closed').find('.level-one-folder .userPermissionCheckBox-level-one').prop('checked', false).attr('isChecked', 'false'); $(this).closest('.level-two-closed').find('.level-two-folder .userPermissionCheckBox-level-two').prop('checked', false).attr('isChecked', 'false'); } else { $(this).attr('isChecked', 'true'); $(this).closest('.level-one-closed').find('.level-one-folder .userPermissionCheckBox-level-one').prop('checked', true).attr('isChecked', 'true'); $(this).closest('.level-two-closed').find('.level-two-folder .userPermissionCheckBox-level-two').prop('checked', true).attr('isChecked', 'true'); } }); 

http://jsfiddle.net/xzigraz/BTXNk/3/

+2
source share

As Matt said , you need to check the box of three states with a state when some sub-items are checked and some are not.

You can make a three-position flag by making the third state โ€œundefinedโ€. You can check the "indefinitely" checkbox with $(this).prop("indeterminate", true); . The flag will look something like this: indeterminate checkbox .

See the article article on undefined flags . This article not only explains the vague checkboxes, but has a demonstration of what you want in โ€œUse Caseโ€? in the middle - although the article says that the demo is incomplete because it only checks one level up. Here is the code that uses the demo:

 $(function() { // Apparently click is better chan change? Cuz IE? $('input[type="checkbox"]').change(function(e) { var checked = $(this).prop("checked"), container = $(this).parent(), siblings = container.siblings(); container.find('input[type="checkbox"]').prop({ indeterminate: false, checked: checked }); function checkSiblings(el) { var parent = el.parent().parent(), all = true; el.siblings().each(function() { return all = ($(this).children('input[type="checkbox"]').prop("checked") === checked); }); if (all && checked) { parent.children('input[type="checkbox"]').prop({ indeterminate: false, checked: checked }); checkSiblings(parent); } else if (all && !checked) { parent.children('input[type="checkbox"]').prop("checked", checked); parent.children('input[type="checkbox"]').prop("indeterminate", (parent.find('input[type="checkbox"]:checked').length > 0)); checkSiblings(parent); } else { el.parents("li").children('input[type="checkbox"]').prop({ indeterminate: true, checked: false }); } } checkSiblings(container); }); }); 
+2
source share
 $(document).ready(function () { $('input[type=checkbox]').click(function () { // if is checked if ($(this).is(':checked')) { $(this).parents('li').children('input[type=checkbox]').prop('checked', true); $(this).parent().find('li input[type=checkbox]').prop('checked', true); } else { $(this).parents('li').children('input[type=checkbox]').prop('checked', false); // uncheck all children $(this).parent().find('li input[type=checkbox]').prop('checked', false); } }); }); 
0
source share

All Articles