Redbox
Redbox

Reputation: 1477

JQuery: Checkbox how to uncheck child and subchild when parent is unchecked

i already done the select part, but how to do the uncheck part. when i uncheck the parent, it will uncheck the child and its subchild, when uncheck its child will uncheck its subchild.

my code are like this:

the table:

<table border="1">

 <tr>
   <td>Parent</td>
   <td>Child</td>
 </tr>
 <tr>
   <td><input type="checkbox" level="parent" name="someparent1" value="1">Parent 1</td>
   <td>
     <li style="list-style-type:none;"><input type="checkbox" level="child"  name="somename1" value"1"> Child 1</li>
     <li style="list-style-type:none;"><input type="checkbox" level="child"  name="somename2" value"2"> Child 2</li>
     <li style="list-style-type:none;">&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" level="subchild" name="somename1" value="3">Sub Child 1</li>
     <li style="list-style-type:none;">&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" level="subchild" name="somename2" value="3">Sub Child 2</li>
     <li style="list-style-type:none;"><input type="checkbox" level="child"  name="somename3" value"3"> Child 3</li>
   </td>
 </tr>
 <tr>
   <td><input type="checkbox" level="parent" name="someparent1" value="1">Parent 2</td>
   <td>
     <li style="list-style-type:none;"><input type="checkbox" level="child"  name="somename1" value"1"> Child 1</li>
     <li style="list-style-type:none;">&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" level="subchild" name="somename1" value="3">Sub Child 1</li>
     <li style="list-style-type:none;">&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" level="subchild" name="somename2" value="3">Sub Child 2</li>
     <li style="list-style-type:none;">&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" level="subchild" name="somename3" value="3">Sub Child 3</li>
     <li style="list-style-type:none;">&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" level="subchild" name="somename4" value="3">Sub Child 4</li>   
     <li style="list-style-type:none;"><input type="checkbox" level="child"  name="somename2" value"2"> Child 2</li>
     <li style="list-style-type:none;"><input type="checkbox" level="child"  name="somename3" value"3"> Child 3</li>    
   </td>
 </tr>
 <tr>
   <td><input type="checkbox" level="parent" name="someparent1" value="1">Parent 3</td>
   <td>
     <li style="list-style-type:none;"><input type="checkbox" level="child"  name="somename1" value"1"> Child 1</li>
     <li style="list-style-type:none;"><input type="checkbox" level="child"  name="somename2" value"2"> Child 2</li>
     <li style="list-style-type:none;"><input type="checkbox" level="child"  name="somename3" value"3"> Child 3</li>
     <li style="list-style-type:none;">&nbsp;&nbsp;&nbsp;&nbsp;Others Reason: <input type="text" level="subchild" size="50" name="other" ></li>      
   </td>
 </tr>   

</table>

the jquery:

//for child checkbox clicked to select parent
$('input[@type=checkbox][level="child"]').click(function (event) {
        var checked = $(this).is(':checked');
        if (checked) {
            $(this).closest('td').parent().children('td').first('td').children('input[@type=checkbox][level="parent"]').attr('checked', true);
        }   

});

//for subchild checkbox clicked to select child + parent
$('input[@type=checkbox][level="subchild"]').click(function (event) {
            var checked = $(this).is(':checked');

            if (checked) {
// Two select Parent element   
$(this).closest('td').parent().children('td').first('td').children('input[@type=checkbox][level="parent"]').attr('checked', true);

// Two select Child element. You will have to loop through all the li elements to //find the appropriate child element 

                $(this).parent().prevAll('li').each(function () {
                    var found = $(this).children('input[@type=checkbox]').attr('level') == 'child';
                    if (found) {
                        $(this).children('input[@type=checkbox][level="child"]').attr('checked', true);
                        return false;
                    }//end if
                });
            }//end if
});



//for subchild text changed to select child + parent
$('input[@type=text][level="subchild"]').keyup(function(event) {
            var keyvalx = $(this).val();

            //if the value of the text area is not empty
            if (keyvalx != '') {
// Two select Parent element   
$(this).closest('td').parent().children('td').first('td').children('input[@type=checkbox][level="parent"]').attr('checked', true);

// Two select Child element. You will have to loop through all the li elements to //find the appropriate child element 

                $(this).parent().prevAll('li').each(function () {
                    var found = $(this).children('input[@type=checkbox]').attr('level') == 'child';
                    if (found) {
                        $(this).children('input[@type=checkbox][level="child"]').attr('checked', true);
                        return false;
                    }//end if
                });
            } //end if
});

jsfiddle: http://jsfiddle.net/YDgHN/3/

any help would be appreciated.

Upvotes: 0

Views: 8340

Answers (3)

Amit Juneja
Amit Juneja

Reputation: 380

        <script>  

            var checkParent  = function(ref) {
                return $(ref).parent().parent().parent().children().first();

            }

           $('input[type="checkbox"]').click(function(){
                if(this.checked){
                    $(this).parent().children().find('input[type="checkbox"]').attr('checked', true);
                }

                else {
                    var a = checkParent(this);
                    while(a.length > 0 && a.prop("tagName") == "INPUT" )
                     {
                        a.attr("checked", false);
                        a = checkParent(a);

                    }

                }
           });

        </script>  

Just completed this algorithm for a project and thought i'll share it on stack flow

Basically, if you check a parent, all the children are selected and when you uncheck a child, all the parents associated with it will be unnchecked because a Parent can remain checked only if all the children are checked

Make sure all the checkboxes are within li and all the li are within ul otherwise this won't work

sample html

<ul id="a">
        <ul id="b">
            <li id="parentli"><input type="checkbox" id="parent"> Parent
                <ul id="c">
                     <li><input type="checkbox" id="aa">Child 1</li>
                     <li><input type="checkbox" id="ab">Child 2
                        <ul id="d">
                             <li><input type="checkbox" id="aba">Child 2-1</li>
                        </ul>
                     </li>
                     <li><input type="checkbox" id="ac">Child 3</li>
                </ul>
            </li>
        </ul>

   </ul>

Upvotes: 1

Redbox
Redbox

Reputation: 1477

After modified i think this version is perfect: http://jsfiddle.net/YDgHN/21/ not forget credit to other that helped me here:

1) JQuery: uncheck subchild checkbox inside ul li

2) JQuery: Checkbox with 3 level auto select child or parent

<table border="1">

 <tr>
   <td>Parent</td>
   <td>Child</td>
 </tr>
 <tr>
     <td><input type="checkbox" data-level="parent" name="someparent1" value="1" />Parent 1</td>
   <td>
     <ul>  
         <li style="list-style-type:none;"><input type="checkbox" data-level="child"  name="somename1" value="1" /> Child 1</li>
         <li style="list-style-type:none;"><input type="checkbox" data-level="child"  name="somename2" value="2" /> Child 2 <br />
                <ul>
                    <li style="list-style-type:none;"><input type="checkbox" data-level="subchild" name="somename1" value="3" />Sub Child 1</li>
                    <li style="list-style-type:none;"><input type="checkbox" data-level="subchild" name="somename2" value="3" />Sub Child 2</li>
                </ul>
         </li>
         <li style="list-style-type:none;"><input type="checkbox" data-level="child"  name="somename3" value="3" /> Child 3</li>
     </ul>      
   </td>
 </tr>
 <tr>
     <td><input type="checkbox" data-level="parent" name="someparent1" value="1" />Parent 2</td>
   <td>
     <ul>
         <li style="list-style-type:none;"><input type="checkbox" data-level="child"  name="somename1" value= "1" /> Child 1<br /> 
                <ul>
                    <li style="list-style-type:none;"><input type="checkbox" data-level="subchild" name="somename1" value="3" />Sub Child 1</li>
                    <li style="list-style-type:none;"><input type="checkbox" data-level="subchild" name="somename2" value="3" />Sub Child 2</li>
                    <li style="list-style-type:none;"><input type="checkbox" data-level="subchild" name="somename3" value="3" />Sub Child 3</li>
                    <li style="list-style-type:none;"><input type="checkbox" data-level="subchild" name="somename4" value="3" />Sub Child 4</li>    
                </ul>
         </li>
         <li style="list-style-type:none;"><input type="checkbox" data-level="child"  name="somename2" value="2" /> Child 2</li>
         <li style="list-style-type:none;"><input type="checkbox" data-level="child"  name="somename3" value="3" /> Child 3</li>
     </ul>   
   </td>
 </tr>
 <tr>
     <td><input type="checkbox" data-level="parent" name="someparent1" value="1" />Parent 3</td>
   <td>
   <ul>
       <li style="list-style-type:none;"><input type="checkbox" data-level="child"  name="somename1" value="1" /> Child 1</li>
       <li style="list-style-type:none;"><input type="checkbox" data-level="child"  name="somename2" value="2" /> Child 2</li>
       <li style="list-style-type:none;"><input type="checkbox" data-level="child"  name="somename3" value="3" /> Child 3<br />
                <ul>
                    <li style="list-style-type:none;">&nbsp;&nbsp;&nbsp;&nbsp;Others Reason: <input type="text" data-level="subchild" size="50" name="other" /></li>
                </ul>
     </li>
   </ul>     
   </td>
 </tr>   

</table>

JScode:

// ########################### for click child to check parent ###########################
$('input[type=checkbox][data-level="child"]').click(function (event) {
        var checked = $(this).is(':checked');
        if (checked) { //when child checked
            $(this).closest('td').parent().children('td').first('td').children('input[type=checkbox][data-level="parent"]').prop('checked', true); 
        } else { //when child un-checked
            //for click uncheck child to uncheck subchild
            $(this).parent().find('input[type=checkbox][data-level="subchild"]').prop('checked', false);
            //for clear text field  on current table row
            $(this).parent().find('input[type=text][data-level="subchild"]').val('');

            //to count checked child
            var countcheckedchild =  $(this).closest('ul').find('input[type=checkbox][data-level="child"]:checked').length;
            //if checked child == 0 then we uncheck the parent
            if (countcheckedchild == 0)
            {                            
                $(this).closest('td').parent().children('td').first('td').children('input[type=checkbox][data-level="parent"]').prop('checked', false); 
            }
        }
});




//###########################  for click parent to uncheck child+subchild+clear textfield ########################### 
$('input[data-level=parent]').click(function() {
//for uncheck all checkbox on current table row    
$(this).parent().next().find(':checkbox').prop('checked', false); 
//for clear text field  on current table row
$(this).parent().next().find('input[type=text][data-level="subchild"]').val('');
});

//########################### for click subchild to select child+parent ###########################
$('input[type=checkbox][data-level="subchild"]').click(function (event) {
        var checked = $(this).is(':checked');

        if (checked) { //when subchild checked
            // to check parent 
            $(this).closest('td').parent().children('td').first('td').children('input[type=checkbox][data-level="parent"]').prop('checked', true); 
            //to check child
            $(this).parents('li:last').children('input[type=checkbox][data-level="child"]').prop('checked', true); 
        } else { //when subchild unchecked

            //count how many checked subchild left
            var countcheckedsubchild =  $(this).closest('ul').find('input[type=checkbox][data-level="subchild"]:checked').length;
            //if checked child == 0 then we uncheck the child
            if (countcheckedsubchild == 0)
            {
                $(this).parents('li:last').children('input[type=checkbox][data-level="child"]').prop('checked', false); 

                // to count how many child selected  
                var countcheckedchild2 =  $(this).parents().find('input[type=checkbox][data-level="child"]:checked').length;

                //if checked child == 0 then we uncheck the parent
                if (countcheckedchild2 == 0)
                {                           
                $(this).closest('td').parent().children('td').first('td').children('input[type=checkbox][data-level="parent"]').prop('checked', false); 
                }
            }



        }
});




//###########################  for subchild textfield  ########################### 
$('input[type=text][data-level="subchild"]').keyup(function(event) {
            var keyvalx = $(this).val();

                //if the value of the text area is not empty
            if (keyvalx != '') {
                // to check parent 
                $(this).closest('td').parent().children('td').first('td').children('input[type=checkbox][data-level="parent"]').prop('checked', true); 
                //to check child
                $(this).parents('li:last').children('input[type=checkbox][data-level="child"]').prop('checked', true);                     
            } else {
                $(this).parents('li:last').children('input[type=checkbox][data-level="child"]').prop('checked', false); 

                // to count how many child selected  
                var countcheckedchild3 =  $(this).parents().find('input[type=checkbox][data-level="child"]:checked').length;

                //if checked child == 0 then we uncheck the parent
                if (countcheckedchild3 == 0)
                {                           
                $(this).closest('td').parent().children('td').first('td').children('input[type=checkbox][data-level="parent"]').prop('checked', false); 
                }
            }
});

hope it can help any one else who need it.

Upvotes: 1

billyonecan
billyonecan

Reputation: 20270

I'd suggest that you change your level attributes to either classes, or HTML5's custom data- attributes, as they're currently invalid, and your markup won't validate.

With that said, the following will do the trick:-

$('input[level="parent"]').click(function() {
    $(this).parent().next().find(':checkbox').prop('checked', false);                             
});

Here's a fiddle

Upvotes: 2

Related Questions