继续我以前的question处理MVC中的复选框。我一直在做这个this的question,但由于MVC CheckBoxFor
创建的隐藏字段,它似乎无法正常工作。知道为什么吗?这是显示实际html的fiddle
来自CheckboxFor的实际html:
<form role="form">
<ul class="col-xs-3">
<li class="checkbox checkbox-info">
<input id="1" name="[0].IsSelected" type="checkbox" value="true"><input name="[0].IsSelected" type="hidden" value="false">
<label for="1"><b>Faa</b></label>
</li>
<li class="checkbox checkbox-info col-xs-offset-1">
<input id="2" name="[0].SubsCategories[0].IsSelected" type="checkbox" value="true"><input name="[0].SubsCategories[0].IsSelected" type="hidden" value="false">
<label for="2">Faa1</label>
</li>
</ul>
<ul class="col-xs-3">
<li class="checkbox checkbox-info">
<input id="3" name="[1].IsSelected" type="checkbox" value="true"><input name="[1].IsSelected" type="hidden" value="false">
<label for="3"><b>Fee</b></label>
</li>
<li class="checkbox checkbox-info col-xs-offset-1">
<input id="4" name="[1].SubsCategories[0].IsSelected" type="checkbox" value="true"><input name="[1].SubsCategories[0].IsSelected" type="hidden" value="false">
<label for="4">Fee1</label>
</li>
<li class="checkbox checkbox-info col-xs-offset-1">
<input id="5" name="[1].SubsCategories[1].IsSelected" type="checkbox" value="true"><input name="[1].SubsCategories[1].IsSelected" type="hidden" value="false">
<label for="5">Fee2</label>
</li>
</ul>
<ul class="col-xs-3">
<li class="checkbox checkbox-info">
<input id="6" name="[2].IsSelected" type="checkbox" value="true"><input name="[2].IsSelected" type="hidden" value="false">
<label for="6"><b>Fii</b></label>
</li>
<li class="checkbox checkbox-info col-xs-offset-1">
<input id="7" name="[2].SubsCategories[0].IsSelected" type="checkbox" value="true"><input name="[2].SubsCategories[0].IsSelected" type="hidden" value="false">
<label for="7">Fii1</label>
</li>
<li class="checkbox checkbox-info col-xs-offset-1">
<input id="8" name="[2].SubsCategories[1].IsSelected" type="checkbox" value="true"><input name="[2].SubsCategories[1].IsSelected" type="hidden" value="false">
<label for="8">Fii2</label>
</li>
</ul>
<ul class="col-xs-3">
<li class="checkbox checkbox-info">
<input id="9" name="[3].IsSelected" type="checkbox" value="true"><input name="[3].IsSelected" type="hidden" value="false">
<label for="9"><b>Foo</b></label>
</li>
<li class="checkbox checkbox-info col-xs-offset-1">
<input id="10" name="[3].SubsCategories[0].IsSelected" type="checkbox" value="true"><input name="[3].SubsCategories[0].IsSelected" type="hidden" value="false">
<label for="10">Foo1</label>
</li>
</ul>
<ul class="col-xs-3">
<li class="checkbox checkbox-info">
<input id="11" name="[4].IsSelected" type="checkbox" value="true"><input name="[4].IsSelected" type="hidden" value="false">
<label for="11"><b>Fuu</b></label>
</li>
</ul>
<ul class="col-xs-3">
<li class="checkbox checkbox-info">
<input id="12" name="[5].IsSelected" type="checkbox" value="true"><input name="[5].IsSelected" type="hidden" value="false">
<label for="12"><b>Bee</b></label>
</li>
</ul>
<ul class="col-xs-3">
<li class="checkbox checkbox-info">
<input id="13" name="[6].IsSelected" type="checkbox" value="true"><input name="[6].IsSelected" type="hidden" value="false">
<label for="13"><b>Bii</b></label>
</li>
<li class="checkbox checkbox-info col-xs-offset-1">
<input id="14" name="[6].SubsCategories[0].IsSelected" type="checkbox" value="true"><input name="[6].SubsCategories[0].IsSelected" type="hidden" value="false">
<label for="14">Bii1</label>
</li>
</ul>
</form>
我正在尝试检查标题,并且将检查所有子复选框,如果正在检查所有子复选框,则将检查父复选框,反之亦然。
我正在尝试的js:
$('li :checkbox').on('click', function () {
var $chk = $(this),
$li = $chk.closest('li'),
$ul, $parent;
if ($li.has('ul')) {
$li.find(':checkbox').not(this).prop('checked', this.checked)
}
do {
$ul = $li.parent();
$parent = $ul.siblings(':checkbox');
if ($chk.is(':checked')) {
$parent.prop('checked', $ul.has(':checkbox:not(:checked)').length == 0)
} else {
$parent.prop('checked', false)
}
$chk = $parent;
$li = $chk.closest('li');
} while ($ul.is(':not(.someclass)'));
});
更新
我在下面的答案的帮助下使它工作。这是fiddle中的工作答案。我确实按照建议,通过标记复选框是否为父。为了安全起见,我还添加了child-li
类,以便我不会使用可能随时更改的引导程序col-xs-offset-1
。非常感谢你!
答案 0 :(得分:1)
这适用于多层嵌套:
$(document).ready(function(){
$('input[type=checkbox]').on('click', function () {
var currentName = $(this).attr("name")
var parrentVal = $(this).is(":checked");
var childrenPrefix = currentName.substring( 0, currentName.lastIndexOf( "IsSelected" ) );
var childrenInputs = $('input[type=checkbox][name^="'+childrenPrefix+'"]')
childrenInputs.each(function(){
$(this).prop("checked", parrentVal);
})
var suffixIndex = currentName.lastIndexOf('.SubsCategories');
if(suffixIndex > -1)
{
var parntName = currentName.substring( 0, suffixIndex);
var siblingsAndChildren = $('input[type=checkbox][name^="'+parntName+'.SubsCategories"]')
if(siblingsAndChildren.length > 0)
{
var selectedSiblingsAndChildren = $(siblingsAndChildren).filter( ":checked" );
$('input[type=checkbox][name="'+parntName+'.IsSelected"]').prop("checked", selectedSiblingsAndChildren.length === siblingsAndChildren.length);
}
}
})
})
答案 1 :(得分:1)
首先,(正如评论中所指出的),如果你指出哪个是父母,哪个是儿童复选框,那就容易多了。在提供的代码中,这可以隐含,因为看起来孩子li
有类'col-xs-offset-1' - 但是这是一个布局类所以不应该用于语义,因为布局可能会发生变化。
因此,使用当前的html,您可以通过执行以下操作来确定复选框是否为父对象:
var isparent = !$(this).closest("li").is(".col-xs-offset-1");
如上所述,我们建议不要这样做 - 只需处理已经给出的内容。相反,你应该添加类(在下面的例子中'parentCheckbox'和'childCheckbox'已被添加)
<ul class="col-xs-3">
<li class="checkbox checkbox-info">
<input class='parentCheckbox' id="1" name="[0].IsSelected" type="checkbox" value="true"><input name="[0].IsSelected" type="hidden" value="false">
<label for="1"><b>Faa</b></label>
</li>
<li class="checkbox checkbox-info col-xs-offset-1">
<input class='childCheckbox' id="2" name="[0].SubsCategories[0].IsSelected" type="checkbox" value="true"><input name="[0].SubsCategories[0].IsSelected" type="hidden" value="false">
<label for="2">Faa1</label>
</li>
</ul>
然后使用:
var isparent = $(this).is(".parentCheckbox");
(当然,你只需要向父母添加一个类,但是以后可以更容易地明确说明父/子,如果在构建时更有意义,可以将它们添加到li
MVC /剃刀)。
然后在单独的例程中处理父子复选框。
勾选父项时,更新除父项以外的所有复选框以匹配父项:
var checked = chk.is(":checked");
chk.closest("ul")
.find(":checkbox")
.not(chk)
.prop('checked', checked);
勾选孩子后,检查是否勾选了所有子复选框并更新父级:
var parent = chk.closest("ul")
.find("li:not(.col-xs-offset-1)")
.find(":checkbox");
var children = chk.closest("ul")
.find("li.col-xs-offset-1")
.find(":checkbox");
if (children.filter(":checked").length == children.length)
parent.prop("checked", true);
else
parent.prop("checked", false);
以上是上面添加到你的html jsfiddle:http://jsfiddle.net/3xczqogy/6/
最后,布置html表示父/子不是html的工作方式 - 它可能会帮助你弄清楚发生了什么,但有更好的方法来做到这一点。 (在问题代码中,“child”(实际上是兄弟)li
用空格缩进,没有其他标记/节点。