Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@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("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?

This is the output of first dropdownlist where first option is Disabled

I want this please Select Year as Disabled

like image 803
rased Avatar asked Mar 07 '23 18:03

rased


2 Answers

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" })
like image 101
Andrei Avatar answered Mar 29 '23 14:03

Andrei


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
}
like image 35
Martin Avatar answered Mar 29 '23 14:03

Martin