简体   繁体   English

@Html.DropDownList() 占位符为禁用和选中

[英]@Html.DropDownList() Placeholder as Disable and Selected

If I use a @Html.DropDownList() with static values then Placeholder can be created as first option and it is possible to apply Disabled and Selected attribute on this option like this如果我使用带有静态值的@Html.DropDownList()然后可以将占位符创建为第一个选项,并且可以像这样在此选项上应用 Disabled 和 Selected 属性

@Html.DropDownList("month", new List<SelectListItem>
{
    new SelectListItem{ Text="Select Month", Value = "0" , Disabled = true, Selected = true},
    new SelectListItem{ Text="January", Value = "1" },
    new SelectListItem{ Text="February", Value = "2" },
    new SelectListItem{ Text="March", Value = "3" },
    new SelectListItem{ Text="April", Value = "4" },
    new SelectListItem{ Text="May", Value = "5" },
    new SelectListItem{ Text="June", Value = "6" },
    new SelectListItem{ Text="July", Value = "7" },
    new SelectListItem{ Text="August", Value = "8" },
    new SelectListItem{ Text="September", Value = "9" },
    new SelectListItem{ Text="October", Value = "10" },
    new SelectListItem{ Text="November", Value = "11" },
    new SelectListItem{ Text="December", Value = "12" },
}, new {@class = "form-control"})

But if I create dropdown list like with a number range and make a Place holder like this:但是,如果我创建下拉列表,就像一个数字范围,并像这样创建一个占位符:

@Html.DropDownList("year", 
      Enumerable.Range(1900, 200)
          .Select(i => new SelectListItem { Text = i.ToString(), Value = i.ToString() }), 
      "Please Select Year", new { @class = "form-control" })

Is it possible to make this Please Select Year Disabled and Selected?是否可以将此Please Select Year禁用和Please Select Year

这是第一个下拉列表的输出,其中第一个选项已禁用

我想要这个请选择年份为禁用

Note the overload you're using for year drop down gives you no control over the default item appearance.请注意,您在year下拉列表中使用的过载使您无法控制默认项​​目外观。

However you could revert to the same approach you are using for months, with a tiny bit of code:但是,您可以使用少量代码恢复使用数月的相同方法:

@{
    var years = new List<SelectListItem>{
        new SelectListItem{ Text="Select Year", Value = "0" , Disabled = true, Selected = true},
    };

    years.AddRange(Enumerable.Range(1900, 200)
          .Select(i => new SelectListItem { Text = i.ToString(), Value = i.ToString() }));
}

@Html.DropDownList("year", 
      years, 
      new { @class = "form-control" })

DropDownListFor allows to specify a placeholder, but the resulting option is not selected, neither disabled. DropDownListFor允许指定占位符,但结果option未被选中,也未被禁用。

I've come up with this我想出了这个

public static MvcHtmlString CustomDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, IEnumerable<SelectListItem> items, string placeHolder, object htmlAttributes)
{
    var r = htmlHelper.DropDownListFor(expression, items, placeHolder, htmlAttributes).ToString();
    var loc = r.IndexOf(placeHolder);
    r = r.Insert(loc - 1, $" selected disabled");
    return new MvcHtmlString(r);
}

Of course, if you want something more reliable, perhaps use HtmlAgilityPack for the parsing.当然,如果你想要更可靠的东西,也许可以使用 HtmlAgilityPack 进行解析。

With a loose basis on another answer, I've written a few extensions to HtmlHelper that make this easy to implement.在另一个答案的松散基础上,我为HtmlHelper编写了一些扩展,使其易于实现。

To implement in the code, just use as follows:要在代码中实现,只需使用如下:

@Html.DropDownListWithDisabledFirstItemFor(model => model.MyProperty, new SelectList(source, "ID_Property", "Display_Property"), "Select an item")

Change:改变:

  • model.MyProperty to the property name from your model\\viewmodel. model.MyProperty到您的模型\\视图模型中的属性名称。
  • source to the source collection for your drop down list. source到下拉列表的源集合。
  • ID_Property to the name of the ID property on the type in source . ID_Propertysource类型的 ID 属性的名称。
  • Display_Property to the name of the display property on the type in source . Display_Propertysource类型的显示属性的名称。
  • Select an item to the text you want to appear in the disabled item in the drop down list.在下拉列表的禁用项目中Select an item要显示在文本中的项目。

There are overloads of the DropDownListWithDisabledFirstItemFor method that allow for specification of HTML attributes too. DropDownListWithDisabledFirstItemFor方法的重载也允许指定 HTML 属性。 The extensions could be further overloaded if other versions of DropDownListFor are required.如果需要其他版本的DropDownListFor可以进一步重载扩展。

Why this and not the accepted answer?为什么是这个而不是公认的答案?

I don't like the idea that I can specify and option label for my drop down list but have it enabled.我不喜欢我可以为我的下拉列表指定和选项标签但启用它的想法。 The built-in functionality should offer the ability to automatically disable it without having to manually add a SelectListItem to do it.内置功能应该能够自动禁用它,而无需手动添加SelectListItem来执行此操作。

In addition, I really dislike the idea of using JavaScript on the client to disable the first option in the select (which is a suggestion in another post).此外,我真的不喜欢在客户端使用 JavaScript 来禁用选择中的第一个选项的想法(这是另一篇文章中的建议)。 That feels like a total hack to me.这对我来说就像一个完全的黑客。

This implementation allows for the continued use of the option label without having to do anything to the SelectList .此实现允许继续使用选项标签,而无需对SelectList做任何事情。

Extension Code扩展代码

The extension code is in the HtmlHelperExtensions class below:扩展代码在下面的HtmlHelperExtensions类中:

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Mvc.Html;

/// <summary>
/// A class that defines extension methods for a HTML helper.
/// </summary>
public static class HtmlHelperExtensions
{
    #region Methods
    #region _Private_
    private static MvcHtmlString DisableDropDownItem(MvcHtmlString source, string sourceItemName, string sourceItemValue = "", string targetItemValue = "")
    {
        string htmlString;
        MvcHtmlString returnValue;
        string sourceString;

        sourceString = $"<option value=\"{sourceItemValue}\">{sourceItemName}</option>";

        htmlString = source.ToHtmlString();
        if (htmlString.Contains(sourceString))
        {
            string replaceString;

            replaceString = $"<option value=\"{targetItemValue}\" disabled=\"disabled\" selected=\"selected\">{sourceItemName}</option>";
            htmlString = htmlString.Replace(sourceString, replaceString);
        }
        returnValue = new MvcHtmlString(htmlString);

        return returnValue;
    }

    #endregion
    #region _Public_
    /// <summary>
    /// Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items, and option label, with the opton label disabled.
    /// </summary>
    /// <typeparam name="TModel">The type of the model.</typeparam>
    /// <typeparam name="TProperty">The type of the value.</typeparam>
    /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    /// <param name="expression">An expression that identifies the object that contains the properties to display.</param>
    /// <param name="selectList">An IEnumerable of SelectListItem objects that are used to populate the drop-down list.</param>
    /// <param name="optionLabel">A string containing the text for a default empty item. This parameter can be null.</param>
    /// <param name="optionLabelValue">A string containing the value that should be assigned to the option label.</param>
    /// <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
    public static MvcHtmlString DropDownListWithDisabledFirstItemFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel, int optionLabelValue = 0)
    {
        return DisableDropDownItem(htmlHelper.DropDownListFor(expression, selectList, optionLabel), optionLabel, string.Empty, optionLabelValue.ToString());
    }
    /// <summary>
    /// Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items, option label, and HTML attributes, with the opton label disabled.
    /// </summary>
    /// <typeparam name="TModel">The type of the model.</typeparam>
    /// <typeparam name="TProperty">The type of the value.</typeparam>
    /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    /// <param name="expression">An expression that identifies the object that contains the properties to display.</param>
    /// <param name="selectList">An IEnumerable of SelectListItem objects that are used to populate the drop-down list.</param>
    /// <param name="optionLabel">A string containing the text for a default empty item. This parameter can be null.</param>
    /// <param name="htmlAttributes">An IDictionary of key string and value object that contains the HTML attributes to set for the element.</param>
    /// <param name="optionLabelValue">A string containing the value that should be assigned to the option label.</param>
    /// <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
    public static MvcHtmlString DropDownListWithDisabledFirstItemFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel, IDictionary<string, object> htmlAttributes, int optionLabelValue = 0)
    {
        return DisableDropDownItem(htmlHelper.DropDownListFor(expression, selectList, optionLabel, htmlAttributes), optionLabel, string.Empty, optionLabelValue.ToString());
    }
    /// <summary>
    /// Returns an HTML select element for each property in the object that is represented by the specified expression using the specified list items, option label, and HTML attributes, with the opton label disabled.
    /// </summary>
    /// <typeparam name="TModel">The type of the model.</typeparam>
    /// <typeparam name="TProperty">The type of the value.</typeparam>
    /// <param name="htmlHelper">The HTML helper instance that this method extends.</param>
    /// <param name="expression">An expression that identifies the object that contains the properties to display.</param>
    /// <param name="selectList">An IEnumerable of SelectListItem objects that are used to populate the drop-down list.</param>
    /// <param name="optionLabel">A string containing the text for a default empty item. This parameter can be null.</param>
    /// <param name="htmlAttributes">An object that contains the HTML attributes to set for the element.</param>
    /// <param name="optionLabelValue">A string containing the value that should be assigned to the option label.</param>
    /// <returns>An HTML select element for each property in the object that is represented by the expression.</returns>
    public static MvcHtmlString DropDownListWithDisabledFirstItemFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectList, string optionLabel, object htmlAttributes, string optionLabelValue = "0")
    {
        return DisableDropDownItem(htmlHelper.DropDownListFor(expression, selectList, optionLabel, htmlAttributes), optionLabel, string.Empty, optionLabelValue);
    }

    #endregion
    #endregion
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM