Setting default value of a Html.DropDownList()

23,543

Solution 1

When constructing your SelectListItem classes, set the Selected property to true for the item you want initially selected.

Solution 2

What I did in one of my projects and was kind of useful, was to develop 2 more overload for
DropDownListFor which accept selectedValue.

namespace MyMvcApplication.Helpers
{
    public static class ExtensionMethods
    {
        public static MvcHtmlString DropDownListFor<TModel, TProperty>
                             (this HtmlHelper<TModel> helper,
                              Expression<Func<TModel, TProperty>> expression,
                              string selectedValue,
                              IEnumerable<SelectListItem> selectList,
                              string optionLabel,
                              object htmlAttributes)
        {
            if (string.IsNullOrEmpty(selectedValue))
                selectedValue = string.Empty;
            if (selectList != null)
            {
                foreach (SelectListItem sli in selectList)
                {
                    if (sli.Value.ToLower().Trim() == selectedValue.ToLower().Trim())
                    {
                        sli.Selected = true;
                        break;
                    }
                }
            }
            else 
            { 
                selectList = new List<SelectListItem>() 
                                  { new SelectListItem() 
                                          { Text = "", Value = "", Selected = true }
                                  };
            }
            return helper.DropDownListFor(expression, selectList, optionLabel, htmlAttributes);
        }


        public static MvcHtmlString DropDownListFor<TModel, TProperty>
                             (this HtmlHelper<TModel> helper,
                              Expression<Func<TModel, TProperty>> expression,
                              string selectedValue,
                              IEnumerable<SelectListItem> selectList,
                              string optionLabel,
                              IDictionary<string, object> htmlAttributes)
        {
            if (string.IsNullOrEmpty(selectedValue))
                selectedValue = string.Empty;
            if (selectList != null)
            {
                foreach (SelectListItem sli in selectList)
                {
                    if (sli.Value.ToLower().Trim() == selectedValue.ToLower().Trim())
                    {
                        sli.Selected = true;
                        break;
                    }
                }
            }
            else 
            { 
                selectList = new List<SelectListItem>() 
                                  { new SelectListItem() 
                                          { Text = "", Value = "", Selected = true } 
                                  };
            }
            return helper.DropDownListFor(expression, selectList, optionLabel, htmlAttributes);
        }

    }
}

So in Views, I can pass a string as selectedValue to DropDownListFor, like:

@using MyMvcApplication.Helpers

@Html.DropDownListFor(model => model.MyData,
                               "Default Value for DropDownList", //Or Model.MySelectedValue
                               Model.MySelectList, null, mull)
Share:
23,543
ediblecode
Author by

ediblecode

Casual gamer, part-time genius and programmer working in London

Updated on June 23, 2020

Comments

  • ediblecode
    ediblecode almost 4 years

    When it posts back I get the following error:

    The ViewData item that has the key 'ClosingDateDay' is of type 'System.Int32' but must be of type 'IEnumerable'. Any ideas?

    Here's my Controller:

    CompetitionEditViewModel viewModel = new CompetitionEditViewModel
    {
        ClosingDate = competition.CloseDate,
        Description = competition.Description,
        DescriptionHeading = competition.DescriptionHeading,
        ImageAssetId = competition.ImageAssetId,
        IsActive = competition.IsActive,
        MainHeading = competition.MainHeading,
        TermsAndConditions = competition.TermsAndConditions,
        UrlSlug = competition.UrlSlug
    };
    
    viewModel.ClosingDateMonthOptions = new List<SelectListItem>();
    for (int i = 1; i <= 12; i++)
    {
        string monthName = new DateTime(2000, i, 1).ToString("MMMM");
        ((List<SelectListItem>)viewModel.ClosingDateMonthOptions).Add(new SelectListItem { Text = monthName, Value = i.ToString() });
    }
    
    viewModel.ClosingDateDayOptions = new List<SelectListItem>();
    for (int i = 1; i <= 31; i++)
    {
        ((List<SelectListItem>)viewModel.ClosingDateDayOptions).Add(new SelectListItem { Text = i.ToString().PadLeft(2, '0'), Value = i.ToString() });
    }
    
    viewModel.ClosingDateYearOptions = new List<SelectListItem>();
    for (int i = DateTime.Now.Year; i <= DateTime.Now.Year + 3; i++)
    {
        ((List<SelectListItem>)viewModel.ClosingDateYearOptions).Add(new SelectListItem { Text = i.ToString(), Value = i.ToString() });
    }
    

    And heres my view:

    @Html.Uber().LabelFor(x => x.ClosingDateDay, new { @class = "access" })
    @Html.DropDownListFor(x => x.ClosingDateDay, Model.ClosingDateDayOptions, Model.ClosingDateDay)
    
    @Html.Uber().LabelFor(x => x.ClosingDateMonth, new { @class = "access" })
    @Html.DropDownListFor(x => x.ClosingDateMonth, Model.ClosingDateMonthOptions, Model.ClosingDateMonth)
    
    @Html.Uber().LabelFor(x => x.ClosingDateYear, new { @class = "access" })
    @Html.DropDownListFor(x => x.ClosingDateYear, Model.ClosingDateYearOptions, Model.ClosingDateYear)
    
  • Franky
    Franky almost 12 years
    With the overload he is using, he supplies the selected value as the third parameter.
  • Tohid
    Tohid almost 12 years
    There's not such an overload to accept the "default value" for a dropdown. As @tarnbridge said, one of the items in List<SelectListItem> has to have `.selected=true'.
  • ediblecode
    ediblecode almost 12 years
    @Tohid The third overload in Html.DropDownFor() is the other way to set default value. This is what @Franky is talking about