【问题标题】:MVC4 - Implement Cascading Multiselect List Boxes using AjaxMVC4 - 使用 Ajax 实现级联多选列表框
【发布时间】:2015-10-13 17:03:51
【问题描述】:

我正在使用 MVC4,我正在尝试将级联列表框实现到我的一个视图中,我一直在关注 this tutorial 并成功创建了 2 个级联下拉框,但我现在需要列表框的相同类型的功能用户可以选择多个项目。

只是为了澄清用户将能够从下拉列表中选择威胁。

选择威胁后,列表框将填充所选威胁的相关安全事件,用户可以在此处选择多个安全事件或单个安全事件

选择他们选择的安全事件后,另一个列表框将填充与所选安全事件关联的任何控件。

这是我目前所拥有的

查看模型

 public class AddNewRiskVM
    {
        public SelectList RiskTypeList { get; set; }
        public SelectList GroupMembersList { get; set; }
        public SelectList ThreatsList { get; set; }
        public SelectList SecurityEventsList { get; set; }
        public List<int> SelectedSecurityEventsIDs { get; set; }
        public SelectList ISOControlList { get; set; }
        public List<int> AssociatedIsoIDs { get; set; }
        public int ISOControlID { get; set; }

        public AddNewRiskVM()
        {
            SelectedSecurityEventsIDs = new List<int>();
            AssociatedIsoIDs  = new List<int>();
        }       
    }

控制器

public void ConfigureNewRisk(AddNewRiskVM ViewModel)
        { 
            var RiskTypes = _DBContext.RiskTypes;
            var Threats = _DBContext.Threats;

            ViewModel.RiskTypeList = new SelectList(RiskTypes, "ID", "Description");
            ViewModel.GroupMembersList = new SelectList(new List<GroupMember>(), "ID", "Name");
            ViewModel.ThreatsList = new SelectList(Threats, "ID", "Description");
            ViewModel.SecurityEventsList = new SelectList(new List<SecurityEvent>(), "ID", "Description");
            ViewModel.ISOControlList = new SelectList(new List<ISOControl>(), "ID", "Description");
        }

        public ActionResult AddNewRisk()
        {
            AddNewRiskVM ViewModel = new AddNewRiskVM();
            ConfigureNewRisk(ViewModel);

            return View(ViewModel);
        }
     public IEnumerable<ISOControl> GetISOControls(int SecurityEventID)
        {
            var QueryResults = _DBContext
                                   .SecurityEventHasISOControls
                                   .Include("SecurityEventHasISOControls.ISOControlID")
                                   .Where(x => x.SecurityEventID == SecurityEventID)
                                   .Select(x => x.ISOControl);

            return QueryResults;
        }

        public JsonResult GetJsonISOControl(int ID)
        {
            var ISOControlListT = this.GetISOControls(Convert.ToInt32(ID));
            var ISOControlList = ISOControlListT.Select(x => new SelectListItem()
            {
                Text = x.Description,
                Value = x.ID.ToString(),
            });
            return Json(ISOControlList, JsonRequestBehavior.AllowGet);
        }

注意 - 我有与用于安全事件的 GetISOControl 和 GetJsonControl 类似的方法

查看

<div class="containeSelect">
     @using (Html.BeginForm(null, null, new { @id = string.Empty }, FormMethod.Post, new { @id = "AddNewWithSelect" }))
     {
        <h3>Add New Risk</h3>
        <fieldset>

             @Html.DropDownList("RiskType", Model.RiskTypeList, "Select Risk Type", htmlAttributes: new { @class = "CascadeInputBox", onchange = "GetMembers()"})
             @Html.DropDownList("GroupMember", Model.GroupMembersList, "Select Group Member", htmlAttributes: new {@class = "CascadeInputBox", @id = "CascadeDropDownList2"})
             @Html.DropDownList("Threats", Model.ThreatsList, "Select Threat", htmlAttributes: new { @class = "CascadeInputBox", onchange = "GetSecurityEvents()"})
             @Html.ListBoxFor(m => m.SelectedSecurityEventsIDs, Model.SecurityEventsList, htmlAttributes: new { @id = "SelectListEvent", onchange = "GetISOControls()"})
             @Html.ListBox("ISOControls", Model.ISOControlList, htmlAttributes: new { @id = "SelectListISO"})

        </fieldset>
     }

<script>
    function GetISOControls() {
        $.ajax({
            url: "@Url.Action("GetJsonISOControl", "RiskAssesment")",
            dataType: "json",
            type: "GET",
            data: { id: $("#Events").val() },
            error: function () {
            },
            beforeSend: function () {
            },
            success: function (data) {
                var items = "";
                $.each(data, function (i, item) {
                    items += "<option value=\"" + item.Value + "\">" + item.Text + "</option>";
                });
                $("#SelectListISO").html(items);
            }
        });
    }
 </script>
<script>  
    function GetSecurityEvents() {
        $.ajax({  
            url: "@Url.Action("GetJsonSecurityEvent", "RiskAssesment")", 
            dataType: "json",  
            type: "GET",  
            data: { id: $("#Threats").val() },
            error: function () {  
            },  
            beforeSend: function () {  
            },  
            success: function (data) {  
                var items = "";  
                $.each(data, function (i, item) {  
                    items += "<option value=\"" + item.Value + "\">" + item.Text + "</option>";  
                });
               $("#SelectListEvent").html(items);
            }  
        });         
    }  
 </script> 

这是我第一次使用 ajax,我知道我必须以某种方式更改下面的行,因为在我的辅助方法中我没有使用字符串名称,而是使用了 linq 表达式,也许就是这样这是它工作所必需的,现在我看不到其他任何东西,但可能遗漏了什么?

data: { id: $("#Events").val() },

如果有人可以提供任何建议,尤其是关于 ajax 的建议。

提前致谢

【问题讨论】:

    标签: c# jquery ajax asp.net-mvc-4 cascadingdropdown


    【解决方案1】:

    您没有带有id="Events" 的元素。您所指的列表框有id="SelectedSecurityEventIDs"。因为它是一个&lt;select multiple&gt;,它的值是一个数组,所以你需要jQuery.param 方法来序列化你的数据。我建议不要用行为污染你的标记,而是使用Unobtrusive Javascript,这样GetISOControls 脚本将被替换为

    var isoList = $("#SelectListISO"); // cache it
    $('#SelectedSecurityEventIDs').change(function() {
        // create a serialized representation of the selected values
        var data = $.param({ id: $(this).val() }, true);
    
        $.ajax({
            url: "@Url.Action("GetJsonISOControl", "RiskAssesment")",
            dataType: "json",
            type: "GET",
            data: data,
            success: function (data) {
                isoList.empty();
                $.each(data, function (i, item) {
                    isoList.append($('<option></option>').val(item.Value).text(item.Text));
                });
            }
        });
    });
    

    并且控制器方法需要是

    public JsonResult GetJsonISOControl(IEnumerable<int> ID)
    

    因为您要发布一组值(您需要调整查询以适应)。另请注意,无需创建SelectList(它只是将未使用的额外数据发送回客户端)。应该只是

    var ISOControlList = ISOControlListT.Select(x => new
    {
        Text = x.Description,
        Value = x.ID.ToString(),
    });
    

    旁注:

    @Html.ListBox("ISOControls", Model.ISOControlList, ..)
    

    正在创建一个与您的模型无关的控件(它没有名为 ISOControls 的属性,因此不会绑定到您的模型。我认为它应该是

    @Html.ListBoxFor(m => m.AssociatedIsoIDs, Model.ISOControlList, ..)
    

    【讨论】:

    • 感谢 Stephen 的精彩解释和链接文章,它们肯定有助于阐明 Java 脚本块中实际发生的情况,而且现在一切都按预期工作:)
    猜你喜欢
    • 1970-01-01
    • 2020-06-25
    • 1970-01-01
    • 2014-05-31
    • 2020-08-05
    • 2021-09-14
    • 1970-01-01
    • 2015-02-25
    • 1970-01-01
    相关资源
    最近更新 更多