views:

511

answers:

1

This question relates to ASP.NET MVC 2 RC (December drop). The basic problem is that when creating a drop down list with a default selected value, the "selected" attribute is either not rendered to HTML or attributed to the wrong option.

Here's some code to demonstrate the wrong option issue:

Here's a function to generate some values [AttributeService class]:

public static Dictionary<int, string> MonthOfBirth
    {
        get
        {
            Dictionary<int, string> months = new Dictionary<int, string>();
            for (int i = 0; i <= 11; i++)
            {
                months.Add(i, CultureInfo.CurrentUICulture.DateTimeFormat.MonthNames[i]);
            }
            return months;
        }
    }

Here's an extension helper to create a list of SelectListItems:

public static List<SelectListItem> ToSelectList<T>(
        this IEnumerable<T> enumerable,
        Func<T, string> text,
        Func<T, int> value,
        string defaultOption
        )
    {
        var items = enumerable.Select(x => new SelectListItem
        {
            Text = text(x),
            Value = value(x).ToString(),
            Selected = false
        }).ToList();

        items.Insert(0, new SelectListItem
        {
            Text = defaultOption,
            Value = "-1",
            Selected = true
        });

        return items;
    }

This snippet ties the two above together:

 public List<SelectListItem> MonthOfBirthList
    {
        get
        {
            return AttributeService.MonthOfBirth.OrderBy(x => x.Key).ToSelectList(x => x.Value, x => x.Key,
                                                 "Month");
        }
    }

The first two snippets reside in various classes and the third lives in my ViewModel which the Controller just spits out to the View. So in my View I then have:

<%=Html.DropDownListFor(x=>x.MonthOfBirth, Model.MonthOfBirthList, new { @class = "panel_4_month" })%>

Note that my extension method adds a default SelectListItem in at position index 0, with a default value and Selected = true. When I put a break point on the Controller to see what the model contains the list is ordered correctly and the correct option is set to selected.

The HTML that I actually get though is this:

<select class="panel_4_month" id="MonthOfBirth" name="MonthOfBirth">
  <option value="-1">Month</option>
  <option selected="selected" value="0">January</option>
  <option value="1">February</option>
  <option value="2">March</option>
  etc...
</select>

Primary question then is whether my code is wrong or whether there's a bug in the HTML renderer? I'm happy to upload a VS28K solution with sample code somewhere if this isn't enough information. Thanks.

+1  A: 

I can't see your controller method, but I believe the issue is there. If you set the following in your controller you should see Month Selected.

public ActionResult Edit(string id)
{
  User myModel = UserServiceFactory.GetUser(id);
  myModel.MonthOfBirth = -1;
  return View(myModel);
}
PaulN
Aha - I think I get it now, it's expecting the model to provide the default value - whereas I had assumed that setting the appropriate selectlistitem to selected would set the selected flag.Thanks very much!
Reza