Converting HTML.EditorFor into a drop down (html.dropdownfor?)

ZVenue picture ZVenue · Mar 1, 2012 · Viewed 27.3k times · Source

Currently I am using a Html.EditorFor control in a default 'Create' View page like this.

 <%: Html.EditorFor(model => model.IsActive) %> 

I would like to convert this to a drop down with values and still be binded to the model in the view. My question is two fold.

  1. If there are only 2/3 values needed in the drop down..Is there a quick way to explicitly populate 2 or 3 values?

  2. If the list is big and needs to come from a sql query, how to do this?

Thanks in advance for the help.

Answer

Darin Dimitrov picture Darin Dimitrov · Mar 1, 2012

In order to generate a dropdownlist you need 2 properties on your view model: a scalar property to bind the selected value to and a collection property which will contain the items to show in the dropdown.

So you could define a view model:

public class DropDownListViewModel
{
    public string SelectedValue { get; set; }
    public IEnumerable<SelectListItem> Items { get; set; }
}

and then on your main view model have a property of this type:

public DropDownListViewModel Foo { get; set; }

Now you could have a custom editor template for this type (~/Views/Shared/EditorTemplates/DropDownListViewModel.ascx):

<%@ Control 
    Language="C#" Inherits="System.Web.Mvc.ViewUserControl<DropDownListViewModel>" 
%>
<%= Html.DropDownListFor(x => x.SelectedValue, Model.Items) %>

and then in your main view:

<%= Html.EditorFor(x => x.Foo) %> 

Now all that's left is to have your controller action rendering the main view to fill the Foo property with the corresponding values. The could be hardcoded, come from a repository or whatever. It doesn't really matter.

On the other hand if you knew the values in advance you could hardcode them in the editor template (~/Views/Shared/EditorTemplates/YesNoDropDown.ascx):

<%= Html.DropDownList(
    "", 
    new SelectList(
        new[] 
        { 
            new { Value = "true", Text = "Yes" },
            new { Value = "false", Text = "No" },
        }, 
        "Value", 
        "Text",
        Model
    )
) %>

and then:

<%= Html.EditorFor(x => x.IsActive, "YesNoDropDown") %> 

or by decorating the IsActive property on your view model:

[UIHint("YesNoDropDown")]
public bool IsActive { get; set; }

and then:

<%= Html.EditorFor(x => x.IsActive) %>