sakura-bloom
sakura-bloom

Reputation: 4594

Html.DropDownListFor does not select value

I have an action that retrieves data and sends it to a view. In a view I have two dropdown menus.

First drop down shows salutation (such as "Mr.", "Ms.", etc.) and does not select value I sent for some reason. The other dropdown shows language list and correctly selects value I sent to the view. The relevant code in view is shown below.

@Html.DropDownListFor(model => model.Salutation, ViewBag.salutation as IEnumerable<SelectListItem>)

@Html.DropDownListFor(model => model.Language, ViewBag.languages as IEnumerable<SelectListItem>)

In the controller I have the following code to get the dropdown data.

ViewBag.salutation = new List<SelectListItem>() { 
                                        new SelectListItem() { Text = "", Value = "" },
                                        new SelectListItem() { Text = "Mr.", Value = "Mr." }, 
                                        new SelectListItem() { Text = "Ms.", Value = "Ms." }, 
                                        new SelectListItem() { Text = "Mrs.", Value = "Mrs." } 
                                    };

and

var languages = (from l in db.Languages.ToList()
                         select new SelectListItem()
                         {
                             Text = l.Language,
                             Value = l.LanguageId.ToString()
                         }).ToList();
        languages.Insert(0, new SelectListItem() { Text = "", Value = "" });
        ViewBag.languages = languages;

The only difference I could think of is that the languages dropdown has an integer as value, whereas salutation dropdown has text as value. Is this why the salutation dropdown doesn't work? I know I could go through each salutation List<SelectListItem> item and set Selected property based on the value I retrieved from database. But I was hoping there would be a cleaner way to do this.

Any ideas?

Thanks

UPDATE

I decided to do what I did for another project.

IList<SelectListItem> _salutation = new List<SelectListItem>() 
        { 
            new SelectListItem() { Value = "", Text = "" },
            new SelectListItem() { Value = "Mr.", Text = "Mr." }, 
            new SelectListItem() { Value = "Ms.", Text = "Ms." }, 
            new SelectListItem() { Value = "Mrs.", Text = "Mrs." } 
        };
        // I could put the following in the declaration above, but for testing purposes it's in foreach loop.
        foreach (var item in _salutation)
        {
            // compare to what's retrieved from database
            item.Selected = item.Value == _viewData.Salutation;
        }
        ViewBag.salutation = _salutation;

After foreach loop I output .Value, .Selected property of each item in _salutation and I get all the correct values with one item being selected. Inside the view I did the following.

        @foreach (var item in ViewBag.salutation as IEnumerable<SelectListItem>)
        {
            <b>@item.Value : @item.Text : @item.Selected</b><br />
        }

All the correct Text/Values come up but none are Selected! This happens if I output the values after I execute @Html.DropDownListFor(). If I output the ViewBag.salutation before the html helper the correct value is selected.

SOLUTION

I found the following article useful: DropDownListFor with ASP.NET MVC.

Instead of using ViewBag I added the following to the ViewModel. (Showing the part for salutations drop down.)

public class TheViewModel
{
    private IList<string> _salutations = new List<string>() { "", "Mr.", "Ms.", "Mrs." };

    public IEnumerable<SelectListItem> SalutationItems
    {
        get
        {
            var salutations = _salutations.Select(s => new SelectListItem { Value = s, Text= s });
            return salutations;
        }
    }
    // The rest of the ViewModel
}

And in the View I have the following.

@Html.DropDownListFor(model => model.Salutation, Model.SalutationItems)

Upvotes: 2

Views: 10396

Answers (2)

Jaimin
Jaimin

Reputation: 8020

Try this,

@Html.DropDownListFor(m =>m.DDCountryModel,IEnumerable<SelectListItem>)ViewBag.salutation)

@Html.DropDownListFor(model => model.Language, IEnumerable<SelectListItem>)ViewBag.languages)

Your Model should be like this,

 public class Model
{
public IEnumerable<SelectListItem> DDCountryModel{ get; set; }
public IEnumerable<SelectListItem> Language{ get; set; }
}

Upvotes: 0

asymptoticFault
asymptoticFault

Reputation: 4529

Instead of just supplying the list to the DropDownListFor helper you could provide it a SelectList. The SelectList constructor takes the list and allows you to explicitly set the selected value as well as an overload that lets you specify the Text and Value fields.

@Html.DropDownListFor(model => model.Salutation,
                      new SelectList(ViewBag.salutation as IEnumerable<SelectListItem>,
                                     "Value", "Text", Model.Salutation))

Upvotes: 4

Related Questions