我有一个MultiSelectList,我目前正在使用它在我的视图中创建一个ListBoxFor。在我的ViewModel上,我在列表中的每个项目上都有一个附加属性,我希望在HTML中为客户端操作提供这些属性。
我在此列表上方有一个复选框。当用户单击此复选框时,data-x="true"
项应显示在此列表中。如果用户未单击该复选框,则会显示所有项目(data-x="true"
和data-x="false"
)。每次更改复选框时,此逻辑都在客户端完成
我假设最好的方法是在每个选项元素中添加data- *属性。我到底该怎么做呢?我认为需要一个HTMLHelper方法来扩展ListBox的功能,但我不知道从哪里开始,或者这是否是最好的方法呢?
答案 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
)来启用或禁用选项,而不是隐藏它们。