带有自定义参数的 Html.DropDownListFor()

发布于 2024-12-21 07:29:17 字数 657 浏览 1 评论 0原文

例如

<select id="Country" name="Country">
<option data-domain="AN" value="1">Andorra</option>
<option data-domain="UI" value="2">United Arab Emirates</option>
<option data-domain="AF" value="3">Afghanistan</option>

选项具有数据域属性,我可以像这样使用它

@Html.DropDownListFor(m => m.Country, Model.CountryList)

Model.CountryList 是国家/地区变量的数组

class Country
{
    public String Text { get; set; }
    public String Value { get; set; }
    public String Domain { get; set; }
}

我想在 HTML 帮助程序中添加扩展方法来生成选择和选项, 谁能给出解决方案

I want to add extension method in HTML helpers for generating select and options like this

<select id="Country" name="Country">
<option data-domain="AN" value="1">Andorra</option>
<option data-domain="UI" value="2">United Arab Emirates</option>
<option data-domain="AF" value="3">Afghanistan</option>

the options have a data-domain attribute, and I can use it like this

@Html.DropDownListFor(m => m.Country, Model.CountryList)

the Model.CountryList is an arrayh of Country valiables

class Country
{
    public String Text { get; set; }
    public String Value { get; set; }
    public String Domain { get; set; }
}

please can anyone give a solution

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

┊风居住的梦幻卍 2024-12-28 07:29:17

您可以借助自定义帮助程序方法构建 CustomDropdownListFor,如下所示:

自定义帮助程序方法:

public static class CustomHelpers
{    
    public class CustomSelectItem : SelectListItem
    {           
        public string Class { get; set; } 
        public string Disabled { get; set; }
        public string SelectedValue { get; set; }
    }
    
    public static MvcHtmlString CustomDropdownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<CustomSelectItem> list, string selectedValue, string optionLabel, object htmlAttributes = null)
    {
        if (expression == null)
        {
            throw new ArgumentNullException("expression");
        }
        ModelMetadata metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData);
        string name = ExpressionHelper.GetExpressionText((LambdaExpression)expression);
        return CustomDropdownList(htmlHelper, metadata, name, optionLabel, list, selectedValue, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
    }

    private static MvcHtmlString CustomDropdownList(this HtmlHelper htmlHelper, ModelMetadata metadata, string name, string optionLabel, IEnumerable<CustomSelectItem> list, string selectedValue, IDictionary<string, object> htmlAttributes)
    {
        string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
        if (String.IsNullOrEmpty(fullName))
        {
            throw new ArgumentException("name");
        }

        TagBuilder dropdown = new TagBuilder("select");
        dropdown.Attributes.Add("name", fullName);
        dropdown.MergeAttribute("data-val", "true");
        dropdown.MergeAttribute("data-val-required", "Mandatory field.");
        dropdown.MergeAttribute("data-val-number", "The field must be a number.");          
        dropdown.MergeAttributes(htmlAttributes); //dropdown.MergeAttributes(new RouteValueDictionary(htmlAttributes));
        dropdown.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata)); 

        StringBuilder options = new StringBuilder();

        // Make optionLabel the first item that gets rendered.
        if (optionLabel != null)
            options.Append("<option value='" + String.Empty + "'>" + optionLabel + "</option>");

        foreach (var item in list)
        {
            if (item.SelectedValue == "selected" && item.Disabled == "disabled")
                options.Append("<option value='" + item.Value + "' class='" + item.Class + "' selected='" + item.SelectedValue + "' disabled='" + item.Disabled + "'>" + item.Text + "</option>");
            else if (item.SelectedValue != "selected" && item.Disabled == "disabled")
                options.Append("<option value='" + item.Value + "' class='" + item.Class + "' disabled='" + item.Disabled + "'>" + item.Text + "</option>");
            else if (item.SelectedValue == "selected" && item.Disabled != "disabled")
                options.Append("<option value='" + item.Value + "' class='" + item.Class + "' selected='" + item.SelectedValue + "'>" + item.Text + "</option>");
            else
                options.Append("<option value='" + item.Value + "' class='" + item.Class + "'>" + item.Text + "</option>");
        }
        dropdown.InnerHtml = options.ToString();
        return MvcHtmlString.Create(dropdown.ToString(TagRenderMode.Normal));
    }
}

查看 (剃须刀):

@Html.CustomDropdownListFor(m => m.PersonId, ViewBag.PersonData as List<CustomHelpers.CustomSelectItem>, null, "---- Select ----", 
    new { name = "personId", id = "personId"})                   
@Html.ValidationMessageFor(m => m.PersonId, null , new { @class = "ValidationErrors" })

You can build your CustomDropdownListFor with the help of a custom helper method as shown below:

Custom Helper Method:

public static class CustomHelpers
{    
    public class CustomSelectItem : SelectListItem
    {           
        public string Class { get; set; } 
        public string Disabled { get; set; }
        public string SelectedValue { get; set; }
    }
    
    public static MvcHtmlString CustomDropdownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<CustomSelectItem> list, string selectedValue, string optionLabel, object htmlAttributes = null)
    {
        if (expression == null)
        {
            throw new ArgumentNullException("expression");
        }
        ModelMetadata metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, htmlHelper.ViewData);
        string name = ExpressionHelper.GetExpressionText((LambdaExpression)expression);
        return CustomDropdownList(htmlHelper, metadata, name, optionLabel, list, selectedValue, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
    }

    private static MvcHtmlString CustomDropdownList(this HtmlHelper htmlHelper, ModelMetadata metadata, string name, string optionLabel, IEnumerable<CustomSelectItem> list, string selectedValue, IDictionary<string, object> htmlAttributes)
    {
        string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
        if (String.IsNullOrEmpty(fullName))
        {
            throw new ArgumentException("name");
        }

        TagBuilder dropdown = new TagBuilder("select");
        dropdown.Attributes.Add("name", fullName);
        dropdown.MergeAttribute("data-val", "true");
        dropdown.MergeAttribute("data-val-required", "Mandatory field.");
        dropdown.MergeAttribute("data-val-number", "The field must be a number.");          
        dropdown.MergeAttributes(htmlAttributes); //dropdown.MergeAttributes(new RouteValueDictionary(htmlAttributes));
        dropdown.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata)); 

        StringBuilder options = new StringBuilder();

        // Make optionLabel the first item that gets rendered.
        if (optionLabel != null)
            options.Append("<option value='" + String.Empty + "'>" + optionLabel + "</option>");

        foreach (var item in list)
        {
            if (item.SelectedValue == "selected" && item.Disabled == "disabled")
                options.Append("<option value='" + item.Value + "' class='" + item.Class + "' selected='" + item.SelectedValue + "' disabled='" + item.Disabled + "'>" + item.Text + "</option>");
            else if (item.SelectedValue != "selected" && item.Disabled == "disabled")
                options.Append("<option value='" + item.Value + "' class='" + item.Class + "' disabled='" + item.Disabled + "'>" + item.Text + "</option>");
            else if (item.SelectedValue == "selected" && item.Disabled != "disabled")
                options.Append("<option value='" + item.Value + "' class='" + item.Class + "' selected='" + item.SelectedValue + "'>" + item.Text + "</option>");
            else
                options.Append("<option value='" + item.Value + "' class='" + item.Class + "'>" + item.Text + "</option>");
        }
        dropdown.InnerHtml = options.ToString();
        return MvcHtmlString.Create(dropdown.ToString(TagRenderMode.Normal));
    }
}

View (Razor):

@Html.CustomDropdownListFor(m => m.PersonId, ViewBag.PersonData as List<CustomHelpers.CustomSelectItem>, null, "---- Select ----", 
    new { name = "personId", id = "personId"})                   
@Html.ValidationMessageFor(m => m.PersonId, null , new { @class = "ValidationErrors" })
请远离我 2024-12-28 07:29:17

标准 DropDownList/DropDownListFor 帮助程序不支持此功能。如果您需要此类功能,则必须从头开始编写自定义 HTML 帮助程序。您可以查看此示例。还有另一个

The standard DropDownList/DropDownListFor helpers do not support this. You will have to write a custom HTML helper from scratch if you need such functionality. You may checkout this example. And another one.

心欲静而疯不止 2024-12-28 07:29:17

方法:

 public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListCodeItem> selectList)
        {
            var select = new TagBuilder("select");

            var options = "";
            TagBuilder option;

            foreach (var item in selectList)
            {
                option = new TagBuilder("option");
                option.MergeAttribute("value", item.Value.ToString());
                option.MergeAttribute("data-domain", item.Code.ToString());
                option.SetInnerText(item.Text);
                options += option.ToString(TagRenderMode.Normal) + "\n";
            }

            select.MergeAttribute("data-val", "true");
            select.MergeAttribute("data-val-required", "The field is required.");
            select.MergeAttribute("id", name);
            select.MergeAttribute("name", name);

            select.InnerHtml = options;

            return new MvcHtmlString(select.ToString(TagRenderMode.Normal));
        }

调用:

@Html.DropDownList("name" Model.OrganizationTypeList)

Method:

 public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListCodeItem> selectList)
        {
            var select = new TagBuilder("select");

            var options = "";
            TagBuilder option;

            foreach (var item in selectList)
            {
                option = new TagBuilder("option");
                option.MergeAttribute("value", item.Value.ToString());
                option.MergeAttribute("data-domain", item.Code.ToString());
                option.SetInnerText(item.Text);
                options += option.ToString(TagRenderMode.Normal) + "\n";
            }

            select.MergeAttribute("data-val", "true");
            select.MergeAttribute("data-val-required", "The field is required.");
            select.MergeAttribute("id", name);
            select.MergeAttribute("name", name);

            select.InnerHtml = options;

            return new MvcHtmlString(select.ToString(TagRenderMode.Normal));
        }

Call:

@Html.DropDownList("name" Model.OrganizationTypeList)
萌︼了一个春 2024-12-28 07:29:17

对 Murat 的答案进行轻微重构:

使用 SelectListItem 自己的属性,仅添加是 Class,不要对 val 属性进行硬编码,因为它们已经在模型元数据上读取

public class CustomSelectItem : SelectListItem
{
    public string Class { get; set; }
}

public static MvcHtmlString CustomDropdownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<CustomSelectItem> list, string selectedValue, string optionLabel, object htmlAttributes = null)
{
    if (expression == null)
    {
        throw new ArgumentNullException(nameof(expression));
    }
    var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
    var name = ExpressionHelper.GetExpressionText(expression);
    return CustomDropdownList(htmlHelper, metadata, name, optionLabel, list, selectedValue, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}

private static MvcHtmlString CustomDropdownList(HtmlHelper htmlHelper, ModelMetadata metadata, string name, string optionLabel, IEnumerable<CustomSelectItem> list, string selectedValue, IDictionary<string, object> htmlAttributes)
{
    var fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
    if (string.IsNullOrWhiteSpace(fullName))
    {
        throw new ArgumentException("Name cannot be null or empty.", nameof(name));
    }

    var dropdown = new TagBuilder("select")
    {
        Attributes =
        {
            { "name", fullName } // All other validation attributes are applied automatically by getting them from the metadata, no need to pass them here manually
        }
    };

    dropdown.MergeAttributes(htmlAttributes);
    dropdown.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata));
    var options = new StringBuilder();
    if (!string.IsNullOrEmpty(optionLabel))
    {
        options.Append($"<option value=''>{optionLabel}</option>");
    }

    foreach (var item in list)
    {
        options.Append(CreateOption(item));
    }
    dropdown.InnerHtml = options.ToString();
    return MvcHtmlString.Create(dropdown.ToString(TagRenderMode.Normal));
}

private static string CreateOption(CustomSelectItem item)
{
    var disabledAttribute = item.Disabled ? "disabled" : string.Empty;
    var selectedAttribute = item.Selected ? "selected" : string.Empty;
    return $"<option value='{item.Value}' class='{item.Class}' {disabledAttribute} {selectedAttribute}>{item.Text}</option>";
}

Slight refactor of Murat's answer:

Uses SelectListItem's own properties, only addition is Class, do not hardcode val attributes as they are already read on the model metadata

public class CustomSelectItem : SelectListItem
{
    public string Class { get; set; }
}

public static MvcHtmlString CustomDropdownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<CustomSelectItem> list, string selectedValue, string optionLabel, object htmlAttributes = null)
{
    if (expression == null)
    {
        throw new ArgumentNullException(nameof(expression));
    }
    var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
    var name = ExpressionHelper.GetExpressionText(expression);
    return CustomDropdownList(htmlHelper, metadata, name, optionLabel, list, selectedValue, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}

private static MvcHtmlString CustomDropdownList(HtmlHelper htmlHelper, ModelMetadata metadata, string name, string optionLabel, IEnumerable<CustomSelectItem> list, string selectedValue, IDictionary<string, object> htmlAttributes)
{
    var fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
    if (string.IsNullOrWhiteSpace(fullName))
    {
        throw new ArgumentException("Name cannot be null or empty.", nameof(name));
    }

    var dropdown = new TagBuilder("select")
    {
        Attributes =
        {
            { "name", fullName } // All other validation attributes are applied automatically by getting them from the metadata, no need to pass them here manually
        }
    };

    dropdown.MergeAttributes(htmlAttributes);
    dropdown.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name, metadata));
    var options = new StringBuilder();
    if (!string.IsNullOrEmpty(optionLabel))
    {
        options.Append(
quot;<option value=''>{optionLabel}</option>");
    }

    foreach (var item in list)
    {
        options.Append(CreateOption(item));
    }
    dropdown.InnerHtml = options.ToString();
    return MvcHtmlString.Create(dropdown.ToString(TagRenderMode.Normal));
}

private static string CreateOption(CustomSelectItem item)
{
    var disabledAttribute = item.Disabled ? "disabled" : string.Empty;
    var selectedAttribute = item.Selected ? "selected" : string.Empty;
    return 
quot;<option value='{item.Value}' class='{item.Class}' {disabledAttribute} {selectedAttribute}>{item.Text}</option>";
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文