Jquery check all dynamic checkboxlist in MVC view

2019-09-14 22:04发布

问题:

Recently I created this dynamic checkboxlist and display them in C# MVC Razor view.

<ul>
    @for (int i = 0; i < Model.sites.Count; i++)
    {
        <li>
            @Html.CheckBoxFor(m => m.sites[i].IsCheck)
            @Html.LabelFor(m => m.sites[i].IsCheck, Model.sites[i].SiteName)
            @Html.HiddenFor(m => m.sites[i].SiteId)
            @Html.HiddenFor(m => m.sites[i].SiteName)
        </li>
        for (int j = 0; j < Model.sites[i].Roomz.Count; j++)
        {
            @Html.CheckBoxFor(m => m.sites[i].Roomz[j].IsCheck)
            @Html.LabelFor(m => m.sites[i].Roomz[j].IsCheck, Model.sites[i].Roomz[j].RoomName)
            @Html.HiddenFor(m => m.sites[i].Roomz[j].RoomId)
            @Html.HiddenFor(m => m.sites[i].Roomz[j].RoomName)
        }
    }
</ul>

below image is the display of the checkboxes

How do i use jquery on check the sites.ischeck to check all those sub-item under the same sites? example check CO2 will also check suite 1&2

回答1:

Modify the html so that you can use a relative selector including adding class names to the checkboxes.

<ul>
    @for (int i = 0; i < Model.sites.Count; i++)
    {
        <li>
            @Html.CheckBoxFor(m => m.sites[i].IsCheck, new { class = "parent" })
            @Html.LabelFor(m => m.sites[i].IsCheck, Model.sites[i].SiteName)
            @Html.HiddenFor(m => m.sites[i].SiteId)
            @Html.HiddenFor(m => m.sites[i].SiteName)
            <div> // suggest you style this to give a margin-left so its indented relative to the parent
                for (int j = 0; j < Model.sites[i].Roomz.Count; j++)
                {
                    @Html.CheckBoxFor(m => m.sites[i].Roomz[j].IsCheck, new { class = "child" })
                    @Html.LabelFor(m => m.sites[i].Roomz[j].IsCheck, Model.sites[i].Roomz[j].RoomName)
                    @Html.HiddenFor(m => m.sites[i].Roomz[j].RoomId)
                    @Html.HiddenFor(m => m.sites[i].Roomz[j].RoomName)
                }
            <div>
        </li>
    }
</ul>

Then you can handle the .change() event of the 'parent' checkbox and get the 'child' checkboxes within the same <li> element

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

You will probably also want to handle the the child checkboxes as well, so that if you uncheck any child, the parent will also be unchecked, or if you check a child, and all the children are also checked, the the parent will be checked.

$('.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);
        }
    }
})


回答2:

i think you are doing it i wrong way. Rather then this you can use this code :

    <ul>
@for (int i = 0; i < Model.sites.Count; i++)
{
    <li>
        @Html.CheckBoxFor(m => m.sites[i].IsCheck)
        @Html.LabelFor(m => m.sites[i].IsCheck, Model.sites[i].SiteName)
        @Html.HiddenFor(m => m.sites[i].SiteId)
        @Html.HiddenFor(m => m.sites[i].SiteName)
          <ul>
               for (int j = 0; j < Model.sites[i].Roomz.Count; j++)
              {
                <li>
                   @Html.CheckBoxFor(m => m.sites[i].Roomz[j].IsCheck)
                   @Html.LabelFor(m => m.sites[i].Roomz[j].IsCheck,Model.sites[i].Roomz[j].RoomName)
                   @Html.HiddenFor(m => m.sites[i].Roomz[j].RoomId)
                   @Html.HiddenFor(m => m.sites[i].Roomz[j].RoomName)

               </li>
              }    

         </ul>
      </li>

    }
     </ul>

Now write this code to select subcategories on checkbox change:

    $('input[type="checkbox"]').change(function(){
      if($(this).prop('checked')==true)
        {
          if($(this).find('ul').length>0)//check if child is present or not
            {
              $(this).find('ul li input[type="checkbox"]').each(function(){
                 $(this).prop('checked',true);
             });

            }


         }



    });