ShaneKm
ShaneKm

Reputation: 21348

jquery selecting/unselecting checkboxes in children/parent <li>

I have the following

<ul>
   <li>Main
    <ul>
        <li><input type="checkbox" onclick="$.SelectChildren(this);" /> parent 1
           <ul>
               <li><input type="checkbox" onclick="$.SelectChildren(this);" />sub 1</li>
               <li><input type="checkbox" onclick="$.SelectChildren(this);" />sub 2
                  <ul>
                     <li><input type="checkbox" onclick="$.SelectChildren(this);" />sub sub 2</li>
                     <li><input type="checkbox" onclick="$.SelectChildren(this);" />sub sub 3</li>
                  </ul>
                </li>
            </ul> 
        </li>
        <li><input type="checkbox" onclick="$.SelectChildren(this);" />parent 2</li>
    </ul>
   </li>
</ul>

Now for my JQuery function:

(function ($) {
    $.SelectChildren = function (element) {
        if ($(element).is(':checked')) {
            $(element).parent().find(':checkbox').attr('checked', true);
        }
        else {
            $(element).parent().find(':checkbox').attr('checked', false);
        }
    }
})(jQuery);

how would I unselect ONLY (all)parent checkboxes when un-checking a child

for example: when clicked "sub sub 2" checkbox -> it should uncheck "sub 2" and "parent 1" checkboxes as well.

thanks

Upvotes: 0

Views: 8682

Answers (5)

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: 0

Ravi Ram
Ravi Ram

Reputation: 24488

You can use this code to allow a checkbox to show/hide childer elements OR elements withint a DIV (or in this case a bootstrap group).

Step #1 - apply the class 'switch' to the checkbox Make sure the checkbox id is set

Step #2 - for the element you want to hide/toggle add the class with chcekbox ID

// -------------------------
// Checkbox to toggle related input fields
// Checkbox control class = switch
// -------------------------
$('.switch').each(function() {
    var tItems = $(this).attr('id');
    $('.' + tItems).hide();
});
// Toggle elements
// <div class="control-group applied_before <-- checkbox ID">
$('.switch').change(function () {
    var tItems = $(this).attr('id');
    $('.' + tItems).toggle();
});
// -------------------------
// -------------------------


<fieldset>
    <legend>Criminal History</legend>   
    <div class="control-group">
        <input type="checkbox" name="criminal_offender" id="criminal_offender" class="switch" />
        <label>criminal_offender</label>
    </div>

    <div class="control-group criminal_offender">
        <label>criminal_offense</label>
        <input type="text" name="criminal_offense" id="criminal_offense" />
    </div>

    <div class="control-group criminal_offender">
        <label>criminal_st_code</label>
        <input type="text" name="criminal_st_code" id="criminal_st_code" />
    </div>

    <div class="control-group criminal_offender">
        <label>criminal_date</label>
        <input type="text" name="criminal_date" id="criminal_date" />
    </div>
</fieldset>

Upvotes: 0

Nick Craver
Nick Craver

Reputation: 630579

Use .children() (to get immediate children) instead of .find() (which looks everywhere below) on the .parents() , for example:

(function ($) {
  $.SelectChildren = function (element) {
    $(element).parents().children(':checkbox').attr('checked', element.checked);
  };
})(jQuery);

Since you're passing a boolean, you can just use the .checked property directly as well.

You can give it a try here, the more traditional approach to get the same effect would look like this:

$(function() {
  $(":checkbox").change(function () {
    $(this).parents().children(':checkbox').attr('checked', this.checked);
  });
});

You can give that version a try here.

Upvotes: 2

mkoistinen
mkoistinen

Reputation: 7773

How about:

$(element).parents(":checkbox").attr('checked', false);

UPDATE. This is wrong, see Nick's solution.

Upvotes: 0

mrN
mrN

Reputation: 3770

Identify the parent will a specific class like "parent"

Then

$(".parent").attr("checked", false);

Very Simple

Upvotes: 0

Related Questions