在MVC中选中/取消选中所有CheckboxFor

时间:2015-08-14 05:10:32

标签: javascript jquery asp.net-mvc checkbox

继续我以前的question处理MVC中的复选框。我一直在做这个thisquestion,但由于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。非常感谢你!

2 个答案:

答案 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);
            }
        }

    })
})

Working fiddle

答案 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用空格缩进,没有其他标记/节点。