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("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?
Note the overload you're using for year
drop down gives you no control over the default item appearance.
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" })
With a loose basis on another answer, I've written a few extensions to HtmlHelper
that make this easy to implement.
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.source
to the source collection for your drop down list.ID_Property
to the name of the ID property on the type in source
.Display_Property
to the name of the display property on the type in source
.Select an item
to the text you want to appear in the disabled item in the drop down list.There are overloads of the DropDownListWithDisabledFirstItemFor
method that allow for specification of HTML attributes too. The extensions could be further overloaded if other versions of DropDownListFor
are required.
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.
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). 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
.
Extension Code
The extension code is in the HtmlHelperExtensions
class below:
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With