背景:根据列表或集合,构建复选框控件,从中选取若干选项。比如,构建城市选择控件,城市按照字母分组进行展示。再比如,构建学生选择控件,学生按照城市进行分组展示。常作为分部视图使用。
效果图:
如图,城市以红色字体显示,李雷来自北京,同时Lily和Lucy来自纽约。
HTML代码如下:
1 <table><tr><td><input type="checkbox" id="checkedAll" onclick="whenAllChecked($(this))" /><label>全选</label></td></tr></table> 2 <table id="tableStu"> 3 @{ 4 var tmp = ViewBag.CityList as List<STU>; 5 foreach (var item in tmp.GroupBy(c=>c.City).OrderBy(b=>b.Key)) 6 { 7 <tr><td><input type="checkbox" class="city" onclick="whenCityChecked($(this))" id=@item.Key /><label for=@item.Key style="color:red">@item.Key</label></td></tr> 8 <tr> 9 @foreach(STU s in item.OrderBy(a=>a.Age)) 10 { 11 <td><input type="checkbox" id=@s.ID class="stuCheck" onclick="whenStuChecked($(this))"/><label for=@s.ID>@s.Name</label></td> 12 } 13 </tr> 14 } 15 } 16 </table>
JS代码如下:
1 <script> 2 function whenStuChecked($obj) { 3 var cityChecked = true; 4 var AllChecked = true; 5 $obj.parent().parent().find('input').each(function () { 6 if ($(this).attr('Checked') != "checked") { 7 $obj.parent().parent().prev('tr').find('input').removeAttr('checked'); 8 cityChecked = false; 9 AllChecked = false; 10 } 11 }); 12 if (AllChecked == false) { 13 $("#checkedAll").removeAttr("checked"); 14 } 15 if (cityChecked) { 16 $obj.parent().parent().prev('tr').find('input').attr("checked", "checked"); 17 $obj.parent().parent().parent().find(".city").each(function () { 18 if ($("#checkedAll").attr("checked") != "checked") { 19 AllChecked = false; 20 } 21 }); 22 if (AllChecked == true) { 23 $("#checkedAll").attr("checked", "checked"); 24 25 } 26 //if (AllChecked == false) { 27 // $("#checkedAll").removeAttr("checked"); 28 //} 29 } 30 } 31 function whenAllChecked($obj) { 32 //alert($("#checkedAll").attr("checked")); 33 if ($("#checkedAll").attr("checked") == "checked") { 34 //$("#tableStu").find("input").removeAttr("checked"); 35 $("#tableStu").find("input").each(function () { 36 $(this).attr("checked", "checked"); 37 }); 38 } 39 else { 40 $("#tableStu").find("input").each(function () { 41 $(this).removeAttr("checked") 42 }); 43 44 //$("#tableStu").find("input").attr("checked", "checked"); 45 } 46 } 47 function whenCityChecked($obj) { 48 //alert($obj.attr("checked")); 49 if ($obj.attr("checked") == "checked") { 50 $obj.parent().parent().next('tr').find('input').each(function () { 51 $(this).attr("checked", "checked"); 52 }); 53 var allcheck = true; 54 $("#tableStu").find('.city').each(function () { 55 if ($(this).attr("checked") != "checked") { 56 allcheck = false; 57 } 58 }); 59 if (allcheck) { 60 $("#checkedAll").attr("checked", "checked"); 61 } 62 } 63 else { 64 $obj.parent().parent().next('tr').find('input').each(function () { 65 $(this).removeAttr("checked") 66 67 }); 68 $("#checkedAll").removeAttr("checked"); 69 } 70 71 72 73 //var AllChecked=true; 74 //$obj.parent().parent().parent().find(".city").each(function () { 75 // if($(this).attr("checked")!="checked") 76 // { 77 // AllChecked = false; 78 // } 79 // if(AllChecked==true) 80 // { 81 // $("#checkedAll").attr("checked", "checked"); 82 // } 83 //}) 84 } 85 $(function () { 86 87 }) 88 </script>
后台代码如下:
1 public class CheckBoxController : Controller 2 { 3 // 4 // GET: /CheckBox/ 5 6 public ActionResult Index() 7 { 8 List<STU> stuList = new List<STU>() 9 { 10 new STU{ID=1,Name="Lily",Age=18,City="NewYork"}, 11 new STU{ID=2,Name="Lucy",Age=20,City="NewYork"}, 12 new STU{ID=1,Name="LiLei",Age=18,City="BeiJing"} 13 }; 14 ViewBag.CityList = stuList; 15 return View(); 16 } 17 18 } 19 public class STU 20 { 21 public int ID { get; set; } 22 public string Name { get; set; } 23 public int Age { get; set; } 24 public string City { get; set; } 25 }
关键代码讲解:
- ViewBag.CityList = stuList;通过ViewBag将列表数据传递到,前台页面中。
- var tmp = ViewBag.CityList as List<STU>;获取后台传递过来的列表,并解析成List。
- foreach...foreach 解析列表,按照城市进行分组,按照年龄的大小进行组内排序。详情见:C#中对泛型List进行分组输出元素
- JQuery代码,当勾选每个学生选项时进行判断,如果同组的其他同学是否被勾选,如果有没有勾选的同学,则城市同样不被选中。
-
1 $obj.parent().parent().find('input').each(function () { 2 if ($(this).attr('Checked') != "checked") { 3 $obj.parent().parent().prev('tr').find('input').removeAttr('checked'); 4 } 5 });
其中,prev方法用来查找前一个同胞元素(同级)。且如果checkbox被选中,该属性的值为checked,否则为undifined。
5. $("#checkedAll").removeAttr("checked");移除对某checkbox的选中,主要用于各选择元素之间的联动。
问题:最麻烦的是,处理各个元素之间的联动,如全选,或者选择某一城市,或者是选择某一单个同学,都将可能对其他checkbox产生影响。注意上面的JS代码有不完善的地方,请自行处理。