22

As the question says: How to set selectedValue in DropDownListFor Html helper?

Tried most of the other solutions but none worked that's why I am opening a new question.

Nothing of these helped:

@Html.DropDownListFor(m => m.TipPopustaId, new SelectList(Model.TipoviDepozita, "Id", "Naziv", 2), htmlAttributes: new { @class = "form-control" })

//Not working with or without cast
@Html.DropDownListFor(m => m.TipPopustaId, new SelectList(Model.TipoviDepozita, "Id", "Naziv", (ProjectName.Models.TipDepozita)Model.TipoviDepozita.Single(x => x.Id == 2)), htmlAttributes: new { @class = "form-control" })
@Html.DropDownListFor(m => m.TipPopustaId, new SelectList(Model.TipoviDepozita, "Id", "Naziv", (ProjectName.Models.TipDepozita)Model.TipoviDepozita.Where(x => x.Id == 2).FirstOrDefault()), htmlAttributes: new { @class = "form-control" })

@Html.DropDownListFor(m => m.TipPopustaId, new SelectList(Model.TipoviDepozita, "Id", "Naziv", new SelectListItem() { Value="2", Selected=true}), htmlAttributes: new { @class = "form-control" })

I would like to avoid manual creation of SelectListItems or a ViewModel just for the list if possible.

Dino
  • 467
  • 1
  • 5
  • 14
  • The `DropDownListFor()` sets the selected option based on the value of property `TipPopustaId` (that is bhow model binding works). Set its value in the controller before you pass the model to the view and the correct option will be selected (setting the `Selected` property is ignored when binding to a model property) –  Jan 18 '17 at 12:25
  • I new that and still were trying stupid things. Thank you very much for reminding me. – Dino Jan 18 '17 at 12:35
  • OK I'll check it as answer when I see it. – Dino Jan 18 '17 at 12:38
  • Are you sure 2 exists as an Id in your list ? – Mads... Jan 18 '17 at 13:37
  • First comment is the right answer. While going with model binding with TipPopustaId as binding name the "selectedValue" is ignored no matter how I had written it (wrong or not). So all my tries are incorrect. I just needed to pass correct value from controller and that's it. – Dino Jan 18 '17 at 13:45

5 Answers5

22

When you use the DropDownListFor() (or DropDownList()) method to bind to a model property, its the value of the property that sets the selected option.

Internally, the methods generate their own IEnumerable<SelectListItem> and set the Selected property based on the value of the property, and therefore setting the Selected property in your code is ignored. The only time its respected is when you do not bind to a model property, for example using

@Html.DropDownList("NotAModelProperty", new SelectList(Model.TipoviDepozita, "Id", "Naziv", 2))

Note your can inspect the source code, in particular the SelectInternal() and GetSelectListWithDefaultValue() methods to see how it works in detail.

To display the selected option when the view is first rendered, set the value of the property in the GET method before you pass the model to the view

I also recommend your view model contains a property IEnumerable<SelectListItem> TipoviDepozita and that you generate the SelectList in the controller

var model = new YourModel()
{
    TipoviDepozita = new SelectList(yourCollection, "Id", "Naziv"),
    TipPopustaId = 2 // set the selected option
}
return View(model);

so the view becomes

@Html.DropDownListFor(m => m.TipPopustaId, Model.TipoviDepozita, new { @class = "form-control" })
  • This got me thinking... Can I somehow extend SelectList/SelectListItem to insert data- attributes easier? – Dino Jan 19 '17 at 09:12
  • No, not unless you re-write all the code from the source code to create your own extension methods, and the `SelectListItem` and `SelectList` classes (plus a bit more). Why do you think you need `data-*` attributes? It would be a lot easier to use a bit of javascript. –  Jan 19 '17 at 09:16
  • Well sometimes I need to have other value in options like price, points, or names so I go with select instead of html.helper but than i need to manually apply data-val-* attributes to select that's why I thought it would be possible to have some cleaner, more effective way of handling all that. – Dino Jan 19 '17 at 09:33
  • If you need those values in the view, then you must be using javascript anyway (other wise they should not be there). You can pass a collection (as a property of your model) containing those values to the view, assign that to a javascript array, then handle the change event of the ` –  Jan 19 '17 at 09:40
  • Yes, I am doing that most of the time, except I'm not liking the fact that it's growing and growing in size because of all event handling, inter field calculations, input filtering, jQuery ajax handlers and what not. I haven't yet figured out "namespaces" in java script to achieve clean separation because now it all looks like mumbo jumbo and I hate it. :( – Dino Jan 19 '17 at 10:11
1

Make Sure that your return Selection Value is a String and not and int when you declare it in your model.

Example:

public class MyModel
{
    public string TipPopustaId { get; set; }
}
p.sturge
  • 51
  • 1
1

Just going to add my preferred way of doing this is to render the select statement myself as it gives greater control over the HTML, rather than using the Razor control.

<select class="form-control" id="my-id">
  @foreach (var item in Model.ListOfItems) {
     var selected = "";
     
     if (item.Value == "whatever") {
        selected = "selected='selected'";
     }
    
     <option @selected value="@item.Value">@item.Text</option>
  }
</select>
TheAlbear
  • 5,507
  • 8
  • 51
  • 84
0
public static class EnumHelper
{
    public static SelectList EnumToSelectList<TEnum>(this Type enumType, object selectedValue)
    {  
        return new SelectList(Enum.GetValues(enumType).Cast<TEnum>().ToList().ToDictionary(n=> n), "Key", "Value", selectedValue);
    }
}

And in your View:

@Html.DropDownListFor(model => model.Role, EnumHelper.EnumToSelectList<Role>(typeof(Role), Model.Role),  new { htmlAttributes = new { @class = "padding_right" } })
@Html.ValidationMessageFor(model => model.Role, "", new { @class = "text-danger" })

Instead of EnumToList use any Other List and select Key and Value of your Listtype Properties

Iwo Kucharski
  • 3,735
  • 3
  • 50
  • 66
0

I noticed there is no razor oriented approach, i added below

var prices = from P in Model[idx].prices.Values
             where !P.Key.ToLower().Contains("san")
             select new SelectListItem()
             {
                 Text = P.Key + " Month " + (Convert.ToDecimal(P.Value) + ((Convert.ToDecimal(P.Value) / 100) * 20)).ToString("0.##") + " $",
                 Value = P.Key
             };
prices.ToList()[0].Selected = true;
@Html.DropDownListFor(model => prices.ToList()[0], prices)
Hamit YILDIRIM
  • 4,224
  • 1
  • 32
  • 35