简体   繁体   中英

How do I specify default option with an ASP.Net Core @Html.DropDownListFor?

I have a .cshtml file that looks like this:

@Html.DropDownListFor(
    m => m.MyModel.YesNoQuestion,                    // IHtmlHelper<TModel> htmlHelper
    new SelectList(Enum.GetValues(typeof(YesNo))),   // Expression<Func<TModel,TResult>>,
    "No",    // IEnumerable<Microsoft.AspNetCore.Mvc.Rendering.SelectListItem> selectList (can be "null")
    new { @class = "custom-select", @id = "MyModel.YesNoQuestion" }  // object htmlAttributes
)

Unfortunately, the resulting dropdown looks like this:

No
Yes
No

The rendered HTML looks like this in Chrome Developer tools:

<select class="custom-select" id="MyModel_YesNoQuestion" name="MyModel.YesNoQuestion">
  <option value>No</option>
  <option>Yes</option>
  <option>No</option>
</select>

What I'm trying to accomplish is this:

<select class="custom-select" id="MyModel_YesNoQuestion" name="MyModel.YesNoQuestion">
  <option>Yes</option>
  <option selected>No</option>
</select>

Q: How do I specify the default option in an ASP.Net Core DropdownListFor?

Q: What exactly does the third argument, "No", do? Argument 2 ("new SelectList") generates my dropdown, so what is Argument 3 supposed to be used for?

Instead of using tag helpers, use razor syntax.

Your .cshtml looks like this:

@model SettingsViewModel

<form method="post" asp-controller="Home" asp-action="Index">
    <label asp-for="YesNo">Yes or no?</label>
    <select asp-for="YesNo" asp-items="Html.GetEnumSelectList<YesNoOptions>()"></select>
</form>

Your SettingsViewModel.cs likte his:

    public class SettingsViewModel
    {
        public YesNoOptions YesNo { get; set; } = YesNoOptions.No;
    }

And the YesNoOtpions enum like this:

    public enum YesNoOptions
    {
        No, Yes
    }

As you can see, you still need to set a default value in the view model, as @Mika Tähtinen mentioned in the first answer.

Q: How do I specify the default option in an ASP.Net Core DropdownListFor?

The Html.DropDownListFor<TModel,TProperty> extension method is a strongly typed extension method generates element for the property specified using a lambda expression.

To set the default selected value, we could set it via the first Parameter, .cshtml.cs page code like this:

    public class IndexModel : PageModel
    {
        private readonly ILogger<IndexModel> _logger;

        public IndexModel(ILogger<IndexModel> logger)
        {
            _logger = logger;
        } 
        [BindProperty]
        public YesNo YesNo { get; set; }   //Enum type, used to set the dropdownlist options
        [BindProperty]
        public string YesNoSelected { get; set; } //used to get the Dropdownlist seleted value.
        public void OnGet()
        {
            YesNoSelected = ((int)YesNo.Yes).ToString();  //set the default selected value.
        }
    }
    public enum YesNo
    {
        No, Yes
    }

Code in the .cshtml page: here we have to bind the DropDownList using the Value and Text property, then, we can based on the selected value to set default values:

    @Html.DropDownListFor(m => m.YesNoSelected,     // IHtmlHelper<TModel> htmlHelper
            new SelectList(Enum.GetValues(typeof(YesNo)).OfType<Enum>().Select(x => new SelectListItem
            {
                Text = Enum.GetName(typeof(YesNo), x),
                Value = (Convert.ToInt32(x)).ToString(),
            }), "Value", "Text"),   // Expression<Func<TModel,TResult>>,
            //"Select Options",    // IEnumerable<Microsoft.AspNetCore.Mvc.Rendering.SelectListItem> selectList (can be "null")
            new { @class = "custom-select", @id = "Model.YesNoQuestion" }  // object htmlAttributes
        )

Besides, you could also set the default value via the SelectList(IEnumerable, String, String, Object) method (using the last parameter to set the selected Value), try to use the following code:

    public class IndexModel : PageModel
    {
        private readonly ILogger<IndexModel> _logger;

        public IndexModel(ILogger<IndexModel> logger)
        {
            _logger = logger;
        } 
        [BindProperty]
        public YesNo YesNo { get; set; }   //Enum type, used to set the dropdownlist options
        [BindProperty]
        public string YesNoSelected { get; set; } //used to get the Dropdownlist seleted value.
        public void OnGet()
        { 
           // YesNoSelected = ((int)YesNo.Yes).ToString();  //set the default selected value.
        }
    }
    public enum YesNo
    {
        No, Yes
    }

Code in the .cshtml page:

    @page
    @model IndexModel 

    @Html.DropDownListFor(m => m.YesNoSelected,     // IHtmlHelper<TModel> htmlHelper
            new SelectList(Enum.GetValues(typeof(YesNo)).OfType<Enum>().Select(x => new SelectListItem
            {
                Text = Enum.GetName(typeof(YesNo), x),
                Value = (Convert.ToInt32(x)).ToString(),
            }), "Value", "Text", ((int)YesNo.Yes).ToString()),   // Expression<Func<TModel,TResult>>, //set default selected value.
            //"Select Options",    // IEnumerable<Microsoft.AspNetCore.Mvc.Rendering.SelectListItem> selectList (can be "null")
            new { @class = "custom-select", @id = "Model.YesNoQuestion" }  // object htmlAttributes
        )

The output as below:

在此处输入图片说明

Q: What exactly does the third argument, "No", do? Argument 2 ("new SelectList") generates my dropdown, so what is Argument 3 supposed to be used for?

The third parameter is optional, which will be the first item of the DropDownList. Generally, we could use the add the description or prompt, like this:

    @Html.DropDownListFor(m => m.YesNoSelected,     // IHtmlHelper<TModel> htmlHelper
            new SelectList(Enum.GetValues(typeof(YesNo)).OfType<Enum>().Select(x => new SelectListItem
            {
                Text = Enum.GetName(typeof(YesNo), x),
                Value = (Convert.ToInt32(x)).ToString(),
            }), "Value", "Text", ((int)YesNo.Yes).ToString()),   // Expression<Func<TModel,TResult>>,
            "Select Yes or No",    // IEnumerable<Microsoft.AspNetCore.Mvc.Rendering.SelectListItem> selectList (can be "null")
            new { @class = "custom-select", @id = "Model.YesNoQuestion" }  // object htmlAttributes
        )

The result as shown below:

在此处输入图片说明

If you don't want to add this option, just remove it.

Edit:

Using JavaScript/JQuery method to set the DropDownList default selected value:

    @Html.DropDownListFor(m => m.YesNoSelected,     // IHtmlHelper<TModel> htmlHelper
            new SelectList(Enum.GetValues(typeof(YesNo)).OfType<Enum>().Select(x => new SelectListItem
            {
                Text = Enum.GetName(typeof(YesNo), x),
                Value = (Convert.ToInt32(x)).ToString(),
            }), "Value", "Text"),   // Expression<Func<TModel,TResult>>,
            //"Select Yes or No",    // IEnumerable<Microsoft.AspNetCore.Mvc.Rendering.SelectListItem> selectList (can be "null")
            new { @class = "custom-select", @id = "Model_YesNoQuestion" }  // object htmlAttributes
        )

    <input type="hidden" id="ddldefault" value="1" />

    @section Scripts{
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script type="text/javascript">
            $(function () { 
                var ddldefault = $("#ddldefault").val(); //default selected value.
                $("#Model_YesNoQuestion option").each(function (index, item) {
                    //You could also use the text() method to check whether the option is selected or not.
                    if ($(item).val() == ddldefault) {
                        $(item).attr("selected", "selected");
                    }
                    else {
                        $(item).removeAttr("selected");
                    }
                });
            });
        </script> 
    }

The third argument is for giving an default empty item, so it's not what you want. To get "No" selected by default, you need to set YesNoQuestion in your model to No when you initialize it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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