Set selected value in SelectList after instantiation
Asked Answered
P

10

31

Am I right to think that there is no way to set the selected value in the C# class SelectList after it is created? Isn't that a bit silly?

Panathenaea answered 19/11, 2008 at 13:16 Comment(1)
I must agree with you about it being silly. The SelectList seems to have been purposely "nerfed" to force you into creating more pure (and heavy) view models. A particular case of this is if you want to reuse a select list in a table where each row should base its selected value off another list in your view model. If you want to use SelectList you actually have to create an array of SelectList each preassigned with their selected value as there is no way to select it "on the fly" just before you use it in your razor view code for that particular row.Stanfordstang
P
19

I think you are fighting the framework. The data going into your views should be created at the Last Possible Minute (LPM).

Thinking this way, a SelectList is a type to feed the DropDownList HTML helper. It is NOT a place to store data while you decide how to process it.

A better solution would be to retrieve your data into a List<T> and then initialize the SelectList(s) when you need to. An immediate benefit of this practice is that it allows you to reuse your List<T> for more than one DropDownList, such as:

Country of birth
Country of residence

These SelectLists all use the Countries list of type List<Country>.

You can use your List<T> at the 'last minute' like in this example:

public class TaxCheatsFormViewModel
{
    private List<Country> countries { get; set; }

    public TaxCheat Cheat { get; private set; }
    public SelectList CountryOfBirth { get; private set; }
    public SelectList CountryOfResidence { get; private set; }
    public SelectList CountryOfDomicile { get; private set; }

    public TaxCheatsFormViewModel(TaxCheat baddie)
    {
        TaxCheat = baddie;
        countries = TaxCheatRepository.GetList<Country>();
        CountryOfBirth = new SelectList(countries, baddie.COB);
        CountryOfResidence = new SelectList(countries, baddie.COR);
        CountryOfDomicile = new SelectList(countries, baddie.COD);
    }
}

The point being that you should keep your data in a List<T> till you really need to output it; the last possible minute (LPM).

Philipps answered 12/2, 2010 at 16:48 Comment(1)
This is indeed the way I went. In my view I then create a SelectList from my list. Where applicable, I have a helper method that does this.Panathenaea
B
4

Because this is such a high result in Google, I'm providing what I found to work here (despite the age):

If you are using a Strongly typed View (i.e. the Model has an assigned type), the SelectedValue provided to the Constructor of the SelectList is overwritten by the value of the object used for the Model of the page.

This works well on an edit page, but not for Create when you want to preselect a specific value, so one workaround is simply to assign the correct value on a default constructed object you pass to the view as the Model. e.g.

var model = new SubjectViewModel()
{
   Subject = new Subject(),
   Types = data.SubjectTypes.ToList()
}
model.Subject.SubjectType = model.Types.FirstOrDefault(t => t.Id == typeId);
ViewData.Model = model;
return View();

so the code in my Create View that looks like this:

Html.DropDownListFor(model => model.Subject.SubjectTypeId, new SelectList(model.Types, "Id", "Name"))

returns the Drop Down List with the value I assigned as the SelectedValue in the list.

Bellini answered 9/4, 2011 at 2:6 Comment(0)
D
4

I know it' an old question, but it might help someone out there. I did what looks to be closely like what Erik did. I just created a new SelectList from my existing one...

SelectList myList = GetMySelectList();
SelectListItem selected = myList.FirstOrDefault(x => x.Text.ToUpper().Contains("UNITED STATES"));
if (selected != null)
{
     myList = new SelectList(myList, "value", "text", selected.Value);
}
Detergent answered 5/9, 2012 at 17:52 Comment(0)
N
3

The "SelectedValue" property is read-only. Setting it in the constructor is the only way.

Tor, the SelectList is an ASP.NET MVC construct used to create a drop-down list. Doing it your way should work too, but the SelectList should do it for you (and not in JS) if done properly.

Nominate answered 19/11, 2008 at 13:49 Comment(3)
Why, for the love of god, is it readonly? And why can't you manipulate the items after instantiation? And why then can it not be exposed as a readonly array? This datatype goes beyond me!Panathenaea
If you don't like it, write your own version. Its not that complicated, guy.Affirmation
@ will: True, but I don't think I'm the only one with these feelings towards the SelectList class. SHould we all write our own then?Panathenaea
S
1

I think you can do this in the controller. If you are going to render a drop down list with name/ID StateCode, then you can set the selected state using this code after the SelectList is created:

ViewData["StateCode"] = "VT";

It seems that the drop down list HTML helper looks for a ViewData item with the same name as the drop down list that's being created.

I don't think I like using this technique, but it does seem to work.

I do agree that the SelectList class is a little weak at the moment. I'd like to be able to create a SelectList and then select a value later by either value or text.

Submit answered 1/2, 2009 at 15:26 Comment(1)
I noticed that it starts making sence when you use a regular collection in controller and selectlist only at the very last moment in view. Although I don't really like it that way, it does take away a lot of the friction...Panathenaea
L
0

You mean client-side, in the browser?

var select = document.getElementById('mySelect');
select.options[newIndex].selected = true;
Leathaleather answered 19/11, 2008 at 13:44 Comment(0)
B
0

The SelectList object is readonly after it was created. if you want to select something you better do it like:

<%= Html.DropDownList("clientId", ViewData["clients"] as List<SelectListItem>,)%>

And in the code behind:

    ViewData["clientId"] = "ASD"; //This should be the value of item you want to select
    ViewData["clients"] = clientItemList; //List<SelectListItem>
Beautify answered 12/3, 2009 at 3:33 Comment(1)
I try to stay away from the code behind because this would distribute code between my controller, my view AND my code behind. What I do now is instantiate the SelectListItem in the view. Not how I prefer it, but that's just how the cookie crumbles.Panathenaea
N
0

Could do it pretty easy with jQuery;

$(function() {
    $("#myselectlist option[@value='ItemToSelectValue'].attr('selected', 'true');
});
Night answered 27/8, 2009 at 19:5 Comment(1)
The question is actually talking about the C# type SelectList. I'll update the OP to remove the confusion.Panathenaea
S
0

I needed a dropdown in a editable grid myself with preselected dropdown values. Afaik, the selectlist data is provided by the controller to the view, so it is created before the view consumes it. Once the view consumes the SelectList, I hand it over to a custom helper that uses the standard DropDownList helper. So, a fairly light solution imo. Guess it fits in the ASP.Net MVC spirit at the time of writing; when not happy roll your own...

public static string DropDownListEx(this HtmlHelper helper, string name, SelectList selectList, object selectedValue)
{
    return helper.DropDownList(name, new SelectList(selectList.Items, selectList.DataValueField, selectList.DataTextField, selectedValue));
}
Salangi answered 7/11, 2009 at 22:7 Comment(0)
T
0

I agree with @awrigley and others that it is better to load the selected value using the selectlist constructor in the usual case when you have a single dropdownlist. However, sometimes, one needs to set the selected value on the view, such as when you have a page with n identical dropdowns. Since it is not practical to create such collections in the controller and may not even know in advance how many dropdowns you need, a better approach is to create one instance in the viewmodel as a template with no selected value set and then dynamically create the rest dynamically on the view.

I run into this often when iterating through a list of child items on edit views when the children need dropdowns. In such cases, you can do it like this with one line of code:

@Html.DropDownListFor(x => myViewModelFieldName, new SelectList(Model.MyRawSelectListFromMyViewModel.Select(x=> new {x.Value, x.Text}), "Value", "Text", TheValueYouWantToSelect))
Totalizator answered 10/4, 2013 at 5:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.