jquery multiselect - 从数据库分组

时间:2017-03-27 00:31:00

标签: jquery asp.net-mvc twitter-bootstrap asp.net-mvc-4 jquery-multiselect

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

HTML

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

SCRIPT

$('#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()的{​​{1}}方法返回包含属性SelectListint classIDstring classname的对象,我希望能够对string grade的选项。

1 个答案:

答案 0 :(得分:1)

MVC-4不支持选项组,您需要升级到MVC-5才能使用开箱即用的功能。如果您升级了,请使用SelectList构造函数以及生成IEnumerable<SelectListItem>

,参考Constructing a Select List with OptGroup groups获取示例

如果没有升级,您可以将表示您的组及其选项的模型传递给视图,并使用一些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. 您无法将<select multiple>绑定到Classes属性所在的复杂对象集合 - 模型需要是值类型的集合,并且

  2. 您不能对绑定的属性和SelectList使用相同的名称 - 请参阅Will there be any conflict if i specify the viewBag name to be equal to the model property name inside @Html.DropDownListFor了解更多详情

  3. 在控制器中

    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>