Search code examples
c#asp.net-corerazor

Can I specify the default for a SelectListItem in the .cshtml?


I have a set of dropdown values defined in a global .cs file:

mydropdowns.cs

public class Foo_DropdownValues
{
    public static List<SelectListItem> NoYes { get; } = new List<SelectListItem>
    {
        new SelectListItem { Value = "false", Text = "No"},
        new SelectListItem { Value = "true", Text = "Yes" }
    };
    ...

I'm using these SelectLists in different places in my .cshtml web form:

mypage.cshtml

    <div class="form-group" id="PC_QU10_div">
        <label>@Foo_Questions.QU10</label>
        <select asp-for="Foo_Answers.QU10" asp-items="Foo_DropdownValues.NoYes"></select>
    </div>
    <div class="form-group" id="PC_QU20_div">
        <label>@Foo_Questions.QU20</label>
        <select asp-for="Foo_Answers.QU20" asp-items="Foo_DropdownValues.NoYes"></select>
        ...

I'd like to specify a default of "Yes" for the first item, and a default of "No" for the second?

Q: Is there any way for my to specify an explicit default in the .cshtml markup? On a per-item basis?

My app is written in C# in .Net Core 3.1, if it matters.


Solution

  • When a view has a model type specified, input controls for each of the properties of model object can be created using either the HTML Helper methods (@Html.TextBoxFor, @Html.CheckBoxFor, @Html.RadioButtonFor, @Html.DropdownListFor) etc. or using asp-for attributes in the input controls.

    Both of these above mentioned ways, makes sure that the value entered/selected in the input control will be assigned to the model object properties when form is submitted and also the input controls are populated with the respective property values from the model object if the model object is being passed to the view from the server.

    That's why, in this particular case, if the dropdown needs to have a specific value pre-selected (or by default selected), a value needs to be assigned to the dropdownlist. And it can be easily done by populating value in the property of the model object.

    Consider example below:

    Model class:

    public class PersonData
    {
        public string FirstName { get; set; }
    
        public string LastName { get; set; }
    
        public string Gender { get; set; }
    
        public bool IsMarried { get; set; }
    
        public bool IsLeftHanded { get; set; }
    }
    

    Static list of items for dropdownlist.

    public static class StaticValues
    {
        public static SelectListItem[] Genders
        {
            get
            {
                return new SelectListItem[]
                {
                    new SelectListItem("Male", "Male"),
                    new SelectListItem("Female", "Female")
                };
            }
        }
    
        public static SelectListItem[] YesNoItems
        {
            get
            {
                return new SelectListItem[]
                {
                    new SelectListItem("Yes", "True"),
                    new SelectListItem("No", "False")
                };
            }
        }
    }
    

    View Code:

    @model PersonData;
    @{
        ViewData["Title"] = "Person data";
    }
    
    <div>
        <label asp-for="FirstName">Firstname:</label>
        <input asp-for="FirstName"/>
    </div>
    <div>
        <label asp-for="LastName">Lastname:</label>
        <input asp-for="LastName" />
    </div>
    
    <div>
        <label asp-for="Gender">Firstname:</label>
        <select asp-for="Gender" asp-items="@StaticValues.Genders"></select>
    </div>
    <div>
        <label asp-for="IsMarried">Married:</label>
        <select asp-for="IsMarried" asp-items="@StaticValues.YesNoItems"></select>
    </div>
    
    <div>
        <label asp-for="IsLeftHanded">Left handed:</label>
        <select asp-for="IsLeftHanded" asp-items="@StaticValues.YesNoItems"></select>
    </div>
    

    In the following code from Controller Action method, model object is populated with a few properties with values assigned to them. And the model object is passed to the View.

    public async Task<IActionResult> Index()
        {
            var personData = new PersonData();
            // This assignment should populate the text box with John value
            personData.FirstName = "John";
            // Gender dropdown should have Male pre-selected
            personData.Gender = "Male";
    
            // IsMarried dropwodn should have "Yes" pre-selected.
            personData.IsMarried = true;
            return View(personData);
        }
    

    Following is the view rendered when application is run.

    enter image description here

    In a different use case, there can be a requirement where a specific value needs to be pre-selected by default when model property does not have value assigned to the property.

    In such situations, specific SelectListItem should have Selected property set to true.

    For example, in below list of SelectListItem New York has true passed as third argument in constructor. That will mark that item as selected be-default in the dropdownlist.

    public static SelectListItem[] OfficeLocations
    {
            get
            {
                return new SelectListItem[]
                {
                    new SelectListItem("London", "LON"),
                    new SelectListItem("New York", "NY", true),
                    new SelectListItem("Singapore", "SG")
                };
            }
    }
    

    Now I will add new property OfficeLocation to PersonData class as following.

    public string OfficeLocation { get; set; }

    And add following code to view.

    <div>
        <label asp-for="OfficeLocation">Office location:</label>
        <select asp-for="OfficeLocation" asp-items="@StaticValues.OfficeLocations"></select>
    </div>
    

    Now if the model object does not have any value assigned to OfficeLocation property, the OfficeLocation dropdown will have New York selected by default.

    The view will look as following.

    enter image description here

    I hope this will help you resolve your issue.