在Editor上选择All复选框对于MVC C#视图 [英] Select All checkbox on EditorFor MVC C# View

查看:72
本文介绍了在Editor上选择All复选框对于MVC C#视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我当前的视图显示的是员工列表.显示的所有行和列均受模型限制.

My current view is displaying a list of Employees. All rows and columns displayed are model bound.

请在下面查看我的查看代码:

See my view code below:

@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模型绑定复选框上使用.

My problem is as follows: I can manually select all Notify checkboxes using the first Notify Checkbox code line (i.e. using the EditorFor and CheckBoxFor option) and save the data in the post back event. How do I get the select All checkbox option to work on the EditorFor or CheckBoxFor model bound checkbox.

对我来说,命名的CheckBox选项可以与全选"框一起使用,但是我无法将数据返回到后事件处理程序中.所选通知"列的模型数据返回为空.

For me the named CheckBox option works as intended with the Select All box, but I fail to be able to get the data back to the post event handler. The model data for the selected Notify column is returned as null.

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

The main problem I presume is in the way the automation names the elements for the checkboxes if I look at the generated name and id element codes when debugging (sample output source code data with some of my comments added):

<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>

所以我要么需要获得全选"复选框才能与@ Html.EditorFor或@ Html.CheckBoxFor选项一起使用,否则我需要在事件处理程序中获取@ Html.CheckBox中设置的值.

So I either need to get the Select All checkbox to work with the @Html.EditorFor or @Html.CheckBoxFor options OR I need to obtain the value set in the @Html.CheckBox in the post event handler.

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

I have not been able to get the answers I need in the other, similar questions on the Select or Check All Checkboxes as they appear to use other coding languages. Please help.

请注意:

只需在其中放置明显的内容即可:目的是最后仅保留可选的Notify复选框中的1个.一个会工作的.不是全部三个.由于测试和调试失败,我暂时只显示它们.

Just to put the obvious out there: The intention is to only retain 1 of the selectable Notify checkboxes in the end. The one that will work. Not all three of them. I just have them displayed for now due to my unsuccessful testing and debugging.

推荐答案

由于您的name(和id)属性包括集合索引器,因此可以使用jQuery ),但是使用复选框的类名会更容易.

Because your name (and id) attributes include the collection indexer, you could use a jQuery Attribute Ends With Selector (for example $('input[type="checkbox"][name$="Notify"]')), but this would be easier just using a class name for the checkboxes.

@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"))条件,则POST方法中的EmployeeNotification属性将为null.或者,如果说第三个项目满足该条件,则EmployeeNotification将仅包含前两个记录.您需要为集合索引器添加一个附加输入,以允许DefaultModelBinder绑定非零/非连续索引器

However you have another issue with your code. By default, the DefaultModelBinder required collection indexers to be zero-based and consecutive. If the first item in your collection meets the @if (Model.EmployeeNotification[i].NotifiedOn >= DateTime.Parse("2000-01-01 12:00:00 AM")) condition, then your EmployeeNotification property will be will be null in the POST method. ALternatively, if say the 3rd item meets that condition, then EmployeeNotification will only contain the first 2 records. You need to add an additional input for the collection indexer to allow the DefaultModelBinder to bind non-zero/non-consecutive indexers

@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块变为

In addition, I recommend you delete the other hidden inputs except the one that is the ID proeprty (which I assume is NotificationID). It is just including unnecessary html, since those properties should not be required for saving the data, and it is just allowing malicious users to alter those values. I also recommend your view model contains a (say) bool IsEditable property and you set that value based on the condition in the GET method when you map the data model to the view model, so that the if block becomes just @if (Model.EmployeeNotification[i].IsEditable) { ... } else { ... }

这篇关于在Editor上选择All复选框对于MVC C#视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆