为了账号安全,请及时绑定邮箱和手机立即绑定

EditorFor MVC C# 视图上的全选复选框

EditorFor MVC C# 视图上的全选复选框

C#
元芳怎么了 2022-01-09 10:22:59
我当前的视图正在显示员工列表。显示的所有行和列都是模型绑定的。请参阅下面的视图代码:@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>我的问题如下:我可以使用第一个通知复选框代码行(即使用 EditorFor 和 CheckBoxFor 选项)手动选择所有通知复选框,并将数据保存在回发事件中。如何获得全选复选框选项以在 EditorFor 或 CheckBoxFor 模型绑定复选框上工作。对我来说,命名的 CheckBox 选项与 Select All 框按预期工作,但我无法将数据返回到 post 事件处理程序。所选通知列的模型数据返回为 null。
查看完整描述

2 回答

?
慕慕森

TA贡献1856条经验 获得超17个赞

因为您的name(and 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 >= DateTime.Parse("2000-01-01 12:00:00 AM"))条件,那么您的EmployeeNotification属性将null在 POST 方法中。或者,如果说第 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块就变成了@if (Model.EmployeeNotification[i].IsEditable) { ... } else { ... }


查看完整回答
反对 回复 2022-01-09
?
慕田峪7331174

TA贡献1828条经验 获得超13个赞

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


将自定义 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" })

}

然后对于 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。其余数据保存成功。


查看完整回答
反对 回复 2022-01-09
  • 2 回答
  • 0 关注
  • 237 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号