ListBoxFor向每个选项元素添加数据属性

时间:2016-04-27 17:15:49

标签: javascript c# jquery html asp.net-mvc

我有一个MultiSelectList,我目前正在使用它在我的视图中创建一个ListBoxFor。在我的ViewModel上,我在列表中的每个项目上都有一个附加属性,我希望在HTML中为客户端操作提供这些属性。

我在此列表上方有一个复选框。当用户单击此复选框时,data-x="true"项应显示在此列表中。如果用户未单击该复选框,则会显示所有项目(data-x="true"data-x="false")。每次更改复选框时,此逻辑都在客户端完成

我假设最好的方法是在每个选项元素中添加data- *属性。我到底该怎么做呢?我认为需要一个HTMLHelper方法来扩展ListBox的功能,但我不知道从哪里开始,或者这是否是最好的方法呢?

1 个答案:

答案 0 :(得分:1)

为了能够使用<option>属性生成data=*元素,您需要根据SelectListItem创建自己的类,并为属性添加其他属性,然后生成自己的属性HtmlHelper扩展方法基于System.Web.Mvc.SelectExtensions类中的代码。

更容易处理这个问题的方法是将用于构建SelectList的集合传递给视图,将其分配给javascript数组,然后使用javascript / jquery处理复选框.click()事件并重建<select>元素中的选项列表。在您的情况下,它可能只是根据复选框的值隐藏/显示项目。

例如,如果您有一个选择产品的视图,并且包含一个复选框以将该选择限制为仅限本地制造的产品,那么您的模型可能

public class MyViewModel
{
    public bool UseLocalProductOnly { get; set }
    public int SelectedProduct{ get; set; }
    public IEnumerable<SelectListItem> ProductList { get; set; }
    public IEnumerable<int> LocalProducts { get; set; }
}
public class Product
{
    public int ID { get; set; }
    public string Name { get; set; }
    public bool IsLocalProduct { get; set; }
}

并在控制器中

var products = db.Products;
MyViewModel model = new MyViewModel()
{
    ProductList = new SelectList(products, "ID", "Name"),
    LocalProducts = products.Where(x => x.IsLocalProduct).Select(x => x.ID)
}
return View(model);

并在视图中

@Html.CheckBoxFor(m => m.UseLocalProductOnly)
@Html.DropDownListFor(m => m.SelectedProduct, Model.ProductList)

<script>
    var localProducts = @Html.Raw(Json.Encode(Model.LocalProducts))
    var select = $('#SelectedProduct');
    var options = select.children('option');
    $('#UseLocalProductOnly').click(function() {
        if ($(this).is(':checked')) {
            // reset the selected option if it would otherwise be hidden
            if ($.inArray(Number(select.val()), localProducts) === -1) {
                select.val(localProducts[0]);
            }
            // hide options that are not local products
            $.each(options, function () {
                if ($.inArray(Number($(this).val()), localProducts) === -1) {
                    $(this).hide();
                }
            });
        } else {
            // show all options
            productOptions.show();
        }
    });
</script>

或者,您可以使用.prop('disabled', true);(或false)来启用或禁用选项,而不是隐藏它们。