1

我正在使用 jquery 多选插件 [ https://github.com/davidstutz/bootstrap-multiselect]并将其与数据库值动态绑定。

HTML

@Html.ListBoxFor(m => m.Classes, new SelectList(Model.Classes, "Value", "Text"), new { @id = "classList" })

脚本

$('#classList').multiselect({ enableClickableOptGroups: true });

视图中的模型是一个视图模型,包含一个属性SelectList

public class SearchControlViewModel 
{
    ....
    public SelectList Classes { get; set; }
}

和控制器中的代码

SearchControlViewModel  model = new SearchControlViewModel()
{
    ....
    Classes = new SelectList(repClass.GetClassesByYear(23), "classID", "classname")
};
return View(model);

除了一件事之外,它就像一个魅力 - 我想像这样添加分组/组标题<optgroup>。我怎样才能做到这一点?

GetClassesByYear()用于生成返回的方法返回SelectList一个包含属性的对象int classIDstring classname并且string grade我希望能够将选项分组grade

4

1 回答 1

1

MVC-4 不支持选项组,您需要升级到 MVC-5 才能使用开箱即用的功能。如果您进行升级,请参阅使用 OptGroup 组构建选择列表以获取使用SelectList构造函数的示例,并通过生成IEnumerable<SelectListItem>

在不升级的情况下,您可以将代表您的组及其选项的模型传递给视图,并使用一些 javascript/jquery 来生成元素。首先创建一些额外的视图模型

public class OptionGroupVM
{
    public string GroupName { get; set; }
    public IEnumerable<OptionVM> Options { get; set; }
}
public class OptionVM
{
    public string Value { get; set; }
    public string Text { get; set; }
    public bool IsSelected { get; set; } // Only applicable if your not binding to a model property
}

然后修改您的主视图模型以包含以下内容

public class SearchControlViewModel 
{
    ....
    public IEnumerable<int> SelectedClasses { get; set; }
    public IEnumerable<OptionGroupVM> ClassOptions { get; set; }
}

请注意,您当前的模型和使用ListBoxFor()不正确,因为

  1. 您不能将 a 绑定<select multiple>到您的属性所在的复杂对象的集合Classes- 模型需要是值类型的集合,并且

  2. 您不能对绑定到的属性使用相同的名称,如果我SelectListviewBag 名称指定为与 @Html.DropDownListFor 中的模型属性名称相同,是否会发生冲突以获取更多详细信息

在控制器中

var data = repClass.GetClassesByYear(23);
var groupedOptions = data.GroupBy(x => x.grade).Select(x => new OptionGroupVM()
{
    GroupName = x.Key.ToString(),
    Options = x.Select(y => new OptionVM()
    {
        Value = y.classId.ToString(),
        Text = y.classcame,
    })
});
SearchControlViewModel model = new SearchControlViewModel()
{
    ....
    SelectedClasses = ...., // the values of the options that will be pre-selected
    ClassOptions = groupedOptions
};
return View(model);

并在视图中使用

@Html.ListBoxFor(m => SelectedClasses, Enumerable.Empty<SelectListItem>(), new { id = "classList" })

最初将生成<select>没有任何选项的。然后使用以下脚本生成选项

<script type="text/javascript">
    // Get data
    var listBox = $('#classList');
    var selected = @Html.Raw(Json.Encode(Model.SelectedClasses));
    var groups = @Html.Raw(Json.Encode(Model.ClassOptions));

    // Generate options
    createGroupedOptions(listBox, selected, groups);
    // Attach plug-in
    listBox.multiselect({ enableClickableOptGroups: true });

    // This function could be in an external js file
    function createGroupedOptions(element, selected, groups) {
        for (var i = 0; i < groups.length; i++) {
            var group = groups[i];
            var groupElement = $('<optgroup></optgroup>').attr('label', group.GroupName);
            for(var j = 0; j < group.Options.length; j++) {
                var option = group.Options[j];
                var optionElement = $('<option></option>').val(option.Value).text(option.Text);
                if (selected) {
                    if (selected.toString().indexOf(option.Value) >= 0) {
                        optionElement.attr('selected', 'selected')
                    }
                } else {
                    if (option.IsSelected) {
                        optionElement.attr('selected', 'selected')
                    }
                }

                $(groupElement).append(optionElement);
            }
            $(element).append(groupElement);
        }
    }
</script>
于 2017-03-27T03:15:52.313 回答