【问题标题】:Select All checkbox on EditorFor MVC C# ViewEditorFor MVC C# 视图上的全选复选框
【发布时间】:2019-02-13 04:17:11
【问题描述】:

我当前的视图正在显示员工列表。显示的所有行和列都是模型绑定的。

在下面查看我的视图代码:

@using System.Linq
@using DN_.Extensions
@model DN_.Models.NotificationsModel
<script src="~/Scripts/jquery-3.3.1.min.js"></script>

<script type="text/javascript" language="javascript">
    $(function () {
        $("#checkAll").click(function () {
            $("input[id='cb_Notify']").prop("checked", this.checked).change();
            var count = $("input[name='cb_Notify']:checked").length;
        })

        $("input[id='cb_Notify']").click(function () {
            if ($("input[name='cb_Notify']:checked").length == $("input[id='cb_Notify']").length) {
                $("#checkAll").prop("checked", "checked").change();
            }
            else {
                $("#checkAll").removeProp("checked").change();
            }
        })
    })
</script>

@{
    ViewBag.Title = "Link Employees";
}

<h2>Link Employees</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    <input id="btn_Save" type="submit" value="Save" class="btn btn-default" />

    @Html.ActionLink("Back to List", "Index")
    <p>
        Select All <input type="checkbox" id="checkAll" />
        Select All On Premise <input type="checkbox" id="checkAllOnPremise" />
        Select All Full Timers<input type="checkbox" id="checkAllFullTimers" />
    </p>
    <table class="table">
        <tr>
            <th align=center>Notify?</th>
            <th align=center>Employee Name</th>
            <th align=center>Is On Premise</th>
            <th align=center>Is Full Time</th>
            <th align=center>Notified On</th>
        </tr>

        @for (var i = 0; i < Model.EmployeeNotification.Count; i++)
        {

            <tr>
                <td>
                    @*Do not allow editing of the Notify field for employees who have been sent the notification already*@
                    @if (Model.EmployeeNotification[i].NotifiedOn >= DateTime.Parse("2000-01-01 12:00:00 AM"))
                    {
                        @Html.DisplayFor(modelItem => Model.EmployeeNotification[i].Notify)
                    }
                    else
                    {
                        @*Hidden items for the post back information*@
                        @Html.HiddenFor(modelItem => Model.EmployeeNotification[i].NotificationID)
                        @Html.HiddenFor(modelItem => Model.EmployeeNotification[i].EmployeeID)
                        @Html.HiddenFor(modelItem => Model.EmployeeNotification[i].EmployeeName)

                        @*BELOW 3 LINES ARE THE PROBLEM DESCRIBED*@
                        @Html.EditorFor(modelItem => Model.EmployeeNotification[i].Notify)
                        @Html.CheckBoxFor(modelItem => Model.EmployeeNotification[i].Notify)
                        @*This checkbox below works with the "Select All" option, but data is not posted back.*@
                        @Html.CheckBox("cb_Notify", Model.EmployeeNotification[i].Notify)
                    }
                </td>
                <td>
                    @Model.EmployeeNotification[i].EmployeeName
                </td>
                <td>
                    @Html.DisplayFor(modelItem => Model.EmployeeNotification[i].IsOnPremise)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => Model.EmployeeNotification[i].IsFullTime)
                </td>
                <td>
                    @if (Model.EmployeeNotification[i].NotifiedOn >= DateTime.Parse("2000-01-01 12:00:00 AM"))
                    {
                        @Html.RenderDate(Model.EmployeeNotification[i].NotifiedOn, "dd MMM yyyy")
                    }
                </td>
            </tr>
        }
    </table>
}

我的问题如下: 我可以使用第一个通知复选框代码行(即使用 EditorFor 和 CheckBoxFor 选项)手动选择所有通知复选框,并将数据保存在回发事件中。 如何让全选复选框选项在 EditorFor 或 CheckBoxFor 模型绑定复选框上工作。

对我来说,命名的 CheckBox 选项可以与 Select All 框配合使用,但我无法将数据返回到 post 事件处理程序。所选通知列的模型数据返回为 null。

我认为的主要问题在于,如果我在调试时查看生成的名称和 id 元素代码(添加了我的一些 cmets 的示例输出源代码数据),那么自动化为复选框命名元素的方式:

<td>
    <!--Required, hidden data for post back event handler:-->
    <input name="EmployeeNotification[3].NotificationID" id="EmployeeNotification_3__NotificationID" type="hidden" value="6" data-val-number="The field NotificationID must be a number." data-val="true">
    <input name="EmployeeNotification[3].EmployeeID" id="EmployeeNotification_3__EmployeeID" type="hidden" value="27" data-val-number="The field EmployeeID must be a number." data-val="true">
    <input name="EmployeeNotification[3].EmployeeName" id="EmployeeNotification_3__EmployeeName" type="hidden" value="Charlie">
    <!--@Html.EditorFor element-->
    <input name="EmployeeNotification[3].Notify" id="EmployeeNotification_3__Notify" type="checkbox" value="true" data-val="true" data-val-required="The Notify field is required.">
    <input name="EmployeeNotification[3].Notify" type="hidden" value="false">
    <!--@Html.CheckBoxFor element-->
    <input name="EmployeeNotification[3].Notify" id="EmployeeNotification_3__Notify" type="checkbox" value="true">
    <input name="EmployeeNotification[3].Notify" type="hidden" value="false">
    <!--@Html.CheckBox element-->
    <input name="cb_Notify" id="cb_Notify" type="checkbox" value="true">
    <input name="cb_Notify" type="hidden" value="false">
</td>

所以我要么需要让 Select All 复选框与 @Html.EditorFor 或 @Html.CheckBoxFor 选项一起使用,要么我需要在 post 事件处理程序中获取 @Html.CheckBox 中设置的值。

我无法在“选择或选中所有复选框”上的其他类似问题中获得所需的答案,因为它们似乎使用其他编码语言。请帮忙。

请注意:

只是把显而易见的事情放在那里:目的是最后只保留一个可选的通知复选框。那个会起作用的。不是他们三个。由于我的测试和调试不成功,我现在只显示它们。

【问题讨论】:

    标签: javascript c# jquery razor asp.net-mvc-5


    【解决方案1】:

    因为您的name(和id)属性包含集合索引器,您可以使用jQuery Attribute Ends With Selector(例如$('input[type="checkbox"][name$="Notify"]')),但是这会更容易使用复选框的类名。

    @Html.CheckBoxFor(m => m.EmployeeNotification[i].Notify, new { @class = "notify" })
    

    然后你的脚本就可以了

    // cache for performance
    var checkboxes = $('.notify');
    var total = checkboxes.length;
    var checkall = $('#checkAll');
    
    checkall.change(function() {
        checkboxes.prop('checked', $(this).is(':checked'));
    })
    
    checkboxes.change(function() {
        var count = checkboxes.filter(':checked').length;
      checkall.prop('checked', (count == total));
    })
    

    但是,您的代码还有另一个问题。默认情况下,DefaultModelBinder 要求集合索引器从零开始且连续。如果您的集合中的第一项满足@if (Model.EmployeeNotification[i].NotifiedOn &gt;= DateTime.Parse("2000-01-01 12:00:00 AM")) 条件,那么您的EmployeeNotification 属性将在POST 方法中为null。或者,如果说第 3 项满足该条件,则 EmployeeNotification 将仅包含前 2 条记录。您需要为集合索引器添加额外的输入,以允许 DefaultModelBinder 绑定非零/非连续索引器

    @if (Model.EmployeeNotification[i].NotifiedOn >= DateTime.Parse("2000-01-01 12:00:00 AM"))
    {
        @Html.DisplayFor(m => m.EmployeeNotification[i].Notify)
    }
    else
    {
        @Html.HiddenFor(m => m.EmployeeNotification[i].NotificationID)
        @Html.HiddenFor(m => m.EmployeeNotification[i].EmployeeID)
        @Html.HiddenFor(m => m.EmployeeNotification[i].EmployeeName)
        @Html.CheckBoxFor(m => m.EmployeeNotification[i].Notify, new { @class = "notify" })
        <input type="hidden" name="EmployeeNotification.Index" value="@i" /> // add this
    }
    

    此外,我建议您删除除 ID 属性(我假设为 NotificationID)之外的其他隐藏输入。它只是包含不必要的 html,因为保存数据不应该需要这些属性,它只是允许恶意用户更改这些值。我还建议您的视图模型包含(比如说)bool IsEditable 属性,并且在将数据模型映射到视图模型时根据 GET 方法中的条件设置该值,以便 if 块变为 @987654337 @

    【讨论】:

      【解决方案2】:

      我还利用他的建议中的一些灵感,设法找到了另一个解决上述 Stephen 帖子的方法。不是很干净,但是,嘿,它有效。我绝对推荐斯蒂芬的代码。更加简洁明了。

      1. 将自定义 cb_Notify 复选框移动并隐藏到单元格顶部,以便在每一行中创建它。这将使其可搜索所有行等,我可以在循环中使用它:

        @Html.CheckBox("cb_Notify", Model.EmployeeNotification[i].Notify, new { type = "hidden" })
        @*Do not allow editing of the Notify field for employees who have been sent the notification already*@
        @if (Model.EmployeeNotification[i].NotifiedOn >= DateTime.Parse("2000-01-01 12:00:00 AM"))
        {
            @Html.DisplayFor(modelItem => Model.EmployeeNotification[i].Notify)
        }
        else
        {
            @*Hidden items for the post back information*@
            @Html.HiddenFor(modelItem => Model.EmployeeNotification[i].NotificationID)
            @Html.HiddenFor(modelItem => Model.EmployeeNotification[i].EmployeeID)
            @Html.CheckBoxFor(modelItem => Model.EmployeeNotification[i].Notify, new { @class = "notify" })
        }
        
      2. 然后对于jquery,使用隐藏的复选框循环遍历所有行并设置需要设置的值:

        // cache for performance
        var checkAll = $('#checkAll');
        
        checkAll.click(function () {
            var maxCount = $("input[id='cb_Notify']").length;
            var loopCounter;
            var customer;
            for (loopCounter = 0; loopCounter < maxCount; loopCounter++) {
                customer = $("input[name='EmployeeNotification[" + loopCounter + "].EmployeeName']").val();
                if (customer != null) {
                    $("input[name='EmployeeNotification[" + loopCounter + "].Notify']").prop("checked", this.checked);
                }
            }
            toggleSetAllCheckBoxStates();
        })
        

      我创建的 toggleSetAllCheckBoxStates() 函数是因为有次要要求(超出了这个问题的范围,所以我将把它排除在外)根据数据设置仅选择员工数据的子集。但它遵循与上述示例相同的路线。

      在回发事件中,我过滤掉了空数据,因为已发送通知的数据不包含 EmployeeID。其余数据保存成功。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-27
        • 2014-04-11
        相关资源
        最近更新 更多