Wint
Wint

Reputation: 37

Jquery checkbox not checked when all subitems are checked in C# MVC

Hi I have this Loop here that generate checkboxes from sites to floor to rooms and when I check on the sites all the floors are checked but the reverse way round if I manually check all floors but the site check box is not checked. please help fix my mistakes

<div class="form-group ">
  <ul id="siterecord">
    @for (int i = 0; i < Model.SASites.Count; i++)
    {
      @*Generate the sites*@
      <li>
        @Html.CheckBoxFor(m => m.SASites[i].IsCheck, new { @class = "parent" })
        @Html.LabelFor(m => m.SASites[i].IsCheck, Model.SASites[i].SiteName)
        @Html.HiddenFor(m => m.SASites[i].SiteId)
        @Html.HiddenFor(m => m.SASites[i].SiteName)
        @*Generate the floors for each site*@
        @for (int j = 0; j < Model.SASites[i].SAFloors.Count; j++)
        {
          <div style="margin-left:50px; clear:both;">
            <label>Floor @Model.SASites[i].SAFloors[j].FloorName</label>
          </div>
          <br />
          <div style="margin-left:20px;">
            <ul class="suiterecord">
              @for (int k = 0; k < Model.SASites[i].SAFloors[j].SARooms.Count; k++)
              {
                <li style="float:left;">
                  @Html.CheckBoxFor(m => m.SASites[i].SAFloors[j].SARooms[k].IsCheck, new { @class = "child chkboxCss" })
                  <div class="ARSLabel">
                    @Html.LabelFor(m => m.SASites[i].SAFloors[j].SARooms[k].IsCheck, Model.SASites[i].SAFloors[j].SARooms[k].RoomName)
                    @Html.HiddenFor(m => m.SASites[i].SAFloors[j].SARooms[k].RoomId)
                    @Html.HiddenFor(m => m.SASites[i].SAFloors[j].SARooms[k].RoomName)
                  </div>
                </li>
                if ((k + 1) % 5 == 0)
                {
                  @Html.Raw("</ul><div style='clear:both'></div><br><ul class='suiterecord'>");
                }
              }
            </ul>
            <div style='clear:both'></div><br>
          </div>
        }
      </li>
    }
  </ul>
</div>

Jquery script

<script>
$('.parent').click(function () {
    var isChecked = $(this).is(':checked');
    var children = $(this).closest('li').find('.child');
    $.each(children, function (index, item) {
        $(this).prop('checked', isChecked);
    });
});

$('.child').click(function () {
    var parent = $(this).closest('li').find('.parent');
    var isChecked = $(this).is(':checked');
    if (!isChecked) {
        // the parent must be unchecked
        parent.prop('checked', false);
    } else {
        // check if all siblings have the same checked status
        var siblings = $(this).siblings('.child');
        var total = siblings.length;
        var matches = siblings.filter(function () {
            return $(this).prop('checked') == isChecked;
        }).length;
        if (matches === total) {
            parent.prop('checked', isChecked);
        }
    }
})

My Code now is working fine with checking the parent all the child item is checked. but it is not working the other way round whereby check all child the parent is not checked

Output enter image description here

Upvotes: 1

Views: 669

Answers (3)

ablurb
ablurb

Reputation: 56

As I understood, you want to check all the children when the parent is checked, and check the parent when all the children are checked.

Maybe this fiddle, I developed can help you:

https://jsfiddle.net/xcbq4nb1/2/

What it does is to check the parent when all the children are selected, but not viceversa (i.e if all children are deselected, the parent is still selected, this is done on purpose, but you can tweak it as it depends on the context you are working with). Also, when you check/uncheck the parent, all the children check/uncheck with it (this is tweakable too).

The code is the following :)

$(document).ready(function() {
    $(".parent > div >input").click(function() {
    $(this).closest(".parent").find(".children input[type=checkbox]").prop("checked",$(this).is(":checked"));
  });

  $(".children li > input").click(function(event) {
    var parent = $(this).closest(".parent");
    var chldContainer = parent.find(".children");
    var checkedChildren = chldContainer.find("li input[type=checkbox]:not(:checked)").length;
    if (checkedChildren == 0 && parent.find("input").is(":not(:checked)")) {
        $(this).closest(".parent").find("div > input").prop("checked", true);
    } 
  });
});

Hope it helps.

Upvotes: 0

Amyth
Amyth

Reputation: 32969

You can simply select all the checkboxes and use .prop('checked', false) to uncheck them. For example:

$(document).ready(function(){
    $(document).on('click', 'input#all', function(){
    var isChecked = $('input#all:checked').length > 0 ? true : false;
    $('.rooms').find('.rcb').prop('checked', isChecked);
  })
})

Here is a working fiddle demonstrating both checking and unchecking:

https://jsfiddle.net/94d0f6m0/1/

Also it is a good idea to use .on instead of directly using .click if you generate the checkboxes after the DOM has been loaded for making sure that your code also watches for checkbox elements dynamically added to the DOM after it has been loaded.

Upvotes: 1

madalinivascu
madalinivascu

Reputation: 32354

try this simple function

$('.child').click(function () {
   var parent = $(this).closest('li');//get the parent
   var all = parent.find('.child').length;//get all childs
   var allChecked = parent.find('.child:checked').length;//get all checked
    parent.find('.parent').prop('checked', false);//uncheck
  if(all == allChecked) {
   parent.find('.parent').prop('checked', true);//check if all are checked
  }
})

Upvotes: 0

Related Questions