views:

13447

answers:

15

Hi folks, I create a selectList in my controller, to display in the view.

I'm trying to create it on the fly, sorta thing .. like this...

myViewData.PageOptionsDropDown = 
   new SelectList(new [] {"10", "15", "25", "50", "100", "1000"}, "15");

It compiles, but the output is bad...

<select id="PageOptionsDropDown" name="PageOptionsDropDown">
    <option>10</option>
    <option>15</option>
    <option>25</option>
    <option>50</option>
    <option>100</option>
    <option>1000</option>
</select>

Notice how no item is selected?

How can I fix this??

Update

Just bumping this ... issue still outstanding :(

+20  A: 

This is how I do it

IList<Customer> customers = repository.GetAll<Customer>();
IEnumerable<SelectListItem> selectList = 
    from c in customers
    select new SelectListItem
    {
     Selected = (c.CustomerID == invoice.CustomerID),
     Text = c.Name,
     Value = c.CustomerID.ToString()
    };

At second glance I'm not sure I know what you are after...

mhenrixon
Thank you this helped me figure this stuff out.
Cadoo
Doesn't fix the selected item issue but it is a great way of avoiding magic strings for select lists! Cheers
Alan Christensen
+7  A: 

Using the constructor that accepts items, dataValueField, dataTextField, selectedValue as parameters :

ViewData["myList"] = 
                new SelectList(new[] { "10", "15", "25", "50", "100", "1000" }
                .Select(x => new {value = x, text = x}), 
                "value", "text", "15");

Then in your view :

<%=Html.DropDownList("myList") %>
çağdaş
nice dude :) i like! i was trying to do this .. but i couldn't get the .Select(..) part .. nice :) I'll try it out at home, later :)
Pure.Krome
Heya Cagdas. works great, except the selected field is not selected. any idea? is this a bug in the MVC stuff?
Pure.Krome
Selected item works when you add the SelectList item into ViewData object (as in ViewData["myList"] = new SelectList ..) and then render it with <%=Html.DropDownList("myList") %>. I couldn't get the selected item to work without doing it this way though. Weird.
çağdaş
@Cagdas - hi again dude .. i still haven't figured this out :( What's this about a ViewData??? I have a strongly typed ViewData with it's own property.... ???
Pure.Krome
@Pure.Krome - I took that property from your example in the question. Now I'm editing the code sample. Please see my edit in a few seconds.
çağdaş
A: 

It may be the case that you have some ambiguity in your ViewData:

Take a look Here

KP
+13  A: 

I use an extension method:

usage

var departmentItems = departments.ToSelectList(d => d.Code + 
                                               " - " + d.Description,
                                               d => d.Id.ToString(),
                                               " - ");

var functionItems = customerFunctions.ToSelectList(f => f.Description, 
                                                   f => f.Id.ToString(), 
                                                   " - ");

with

 public static class MCVExtentions
    {
        public static List<SelectListItem> ToSelectList<T>(
            this IEnumerable<T> enumerable, 
            Func<T, string> text, 
            Func<T, string> value, 
            string defaultOption)
        {
            var items = enumerable.Select(f => new SelectListItem()
                                         {
                                             Text = text(f), 
                                             Value = value(f) 
                                         }).ToList();
            items.Insert(0, new SelectListItem()
                        {
                            Text = defaultOption, 
                            Value = "-1" 
                        });
            return items;
        }
    }
Thomas Stock
This answer helped me out enormously - thank you so much!
Reza
nice. I've added a selected Func, a defaultValue option and a second overload without any defaults to specify and this works a treat.By the way if you want to make the return type IEnumerable<SelectListItem> you can use the yield return syntax to make this look really clean
Chris Meek
MCVExtensions? :)
Nathan Taylor
Hahah Nathan - good pickup :)
Pure.Krome
it took him over a year to catch it, tho :-)
Thomas Stock
Ha yeah - it's cause I've not checked that project for _ages_
Pure.Krome
+1  A: 

This is an option:

myViewData.PageOptionsDropDown = new[] 
{
 new SelectListItem { Text = "10", Value = "10" },
 new SelectListItem { Text = "15", Value = "15", Selected = true }
 new SelectListItem { Text = "25", Value = "25" },
 new SelectListItem { Text = "50", Value = "50" },
 new SelectListItem { Text = "100", Value = "100" },
 new SelectListItem { Text = "1000", Value = "1000" },
}
murki
and what is 'selected' ???
Pure.Krome
new SelectListItem { Selected=true, Text = "15", Value = "15" } for the selected value.
Cadoo
oops, yeah, forgot to include 'Selected' property, thanks Cadoo =)
murki
+1  A: 

Using your example this worked for me:

controller:

ViewData["PageOptionsDropDown"] = new SelectList(new[] { "10", "15", "25", "50", "100", "1000" }, "15");

view:

<%= Html.DropDownList("PageOptionsDropDown")%>
Cadoo
Yes that's working for me too. In my case, the list is an Entity Model object. Controller: ViewData["Categories"] = new SelectList(db.Categories.ToList(), "CategoryId", "CategoryName", "15"); View: Html.DropDownList("CategoryId", (SelectList)ViewData["Categories"], "--select--")
Junior Mayhé
A: 

I just ran it like this and had no problems,

public class myViewDataObj
    {
        public SelectList PageOptionsDropDown { get; set; }
    }

public ActionResult About()
        {
            myViewDataObj myViewData = new myViewDataObj();
            myViewData.PageOptionsDropDown =
                  new SelectList(new[] { "10", "15", "25", "50", "100", "1000" }, "15");

            ViewData["myList"] = myViewData.PageOptionsDropDown;
            return View();
        }

and

<%=Html.DropDownList("myList") %>

it also worked if you do this,

public ActionResult About()
        {
            myViewDataObj myViewData = new myViewDataObj();
            myViewData.PageOptionsDropDown =
                  new SelectList(new[] { "10", "15", "25", "50", "100", "1000" });

            ViewData["myListValues"] = myViewData.PageOptionsDropDown;
            ViewData["myList"] = "15";
            return View();
        }

and

<%=Html.DropDownList("myList",(IEnumerable<SelectListItem>)ViewData["myListValues"]) %>
Tony Borf
+3  A: 

It seems if you have a strongly typed view you need to change the ID of the dropdown so that it is NOT the name of a property on the inherrited class. You then need to put some logic in your edit (POST) method to pull off the selected value from the FORMCollection and put it on to your instance before committing your changes.

This is certainly a little strange, but i tried it and it works.

So if you class has a field called CountryId say, and you're displaying a list of country names, make the dropdown have an id of CountryName rather than CountryId, then in the post, you can do something with Collection["CountryName"].

Yes, I had this same problem. Simply changing the name worked. Thanks!
davekaro
+1  A: 

The problem is, SelectList works as designed. The bug is in the design. You may set the Selected Property in SelctedItem, but this will completely be ignored, if you traverse the list with the GetEnumerator() ( or if Mvc does that for you). Mvc will create new SelectfListItems instead.

You have to use the SelectList ctor with the SelectListItem[], the Text-Name, the Value-Name and the SelectedValue. Be aware to pass as SelectedValue the VALUE of SelectListItem, which you want to be selected, not the SelectListItem itself! Example:

SelectList sl = new SelectList( new[]{
  new SelectListItem{ Text="one", Value="1"},
  new SelectListItem{ Text="two", Value="2"},
  new SelectListItem{ Text="three", Value="3"}
}, "Text", "Value", "2" );

(not tested this, but I had the same problem)

then the 2nd option will get the selected="selected" attribute. That looks like good old DataSets ;-)

A: 
MonthRepository monthRepository = new MonthRepository();
IQueryable<MonthEntity> entities = monthRepository.GetAllMonth();
List<MonthEntity> monthEntities = new List<MonthEntity>();

foreach(var r in entities)
{
    monthEntities.Add(r);
}

ViewData["Month"] = new SelectList(monthEntities, "MonthID", "Month", "Mars");
Cactus
A: 

Hey folks, the value selected in the model takes advantage instead of the default item. (I agree I didn't read all posts)

Nibble
A: 

This used to work before MVC 2

protected SelectList GetToDoMemberSelectList(int listID, int? sel)
{
    List<ToDoListMember> members =
        Pipe.BServ().GetToDoListMembers().WithListID(listID).ToList();
    SelectList selectList = new SelectList(members, "UserID", "Name", sel);
    return selectList;
}

if sel was null it wouldn't select anything, if not, it would select the relevant value....what has changed?

Mark
A: 

I can't remember how mvc 1 was setup, but it seems that it wanted the select list named the same as the field it belonged too...

What I found, as someone kind of said above, is that my select lists weren't working in mvc2 when the ViewData they were sent as was named the same as the field.

For example:

<%= Html.DropDownListFor((model => model.ForID), (SelectList)ViewData["ForName"]) %>

works when

<%= Html.DropDownListFor((model => model.ForID), (SelectList)ViewData["ForID"]) %>

does not work as the ViewData name "ForID" is named the same as the field it is working for

Mark
A: 

So using the example from above:

SelectList sl = new SelectList( new[]{
  new SelectListItem{ Text="one", Value="1"},
  new SelectListItem{ Text="two", Value="2"},
  new SelectListItem{ Text="three", Value="3"}
}, "Text", "Value", "2" );

How do I now ask the sl for the SelectedItem.Text ?

A: 

I do it like this:

List<SelectListItem> list = new List<SelectListItem>{
new SelectListItem {Selected = true, Text = "Select", Value = "0"},
new SelectListItem {Selected = true, Text = "1", Value = "1"},
new SelectListItem {Selected = true, Text = "2", Value = "2"}
};
return list.ToArray();

The ToArray() takes care of the problems.

femseks