2

I have two multi-select list boxes; one with months and one with years such as the following:

@Html.ListBoxFor(m => m.IncludeGuestsArrivedInTimeframeMonths, Model.TimeframeMonths)
@Html.ListBoxFor(m => m.IncludeGuestsArrivedInTimeframeYears, Model.TimeframeYears)

I'm saving the both values to the database as a comma separated list (string/nvarchar). The values are being like this: Months: 1,3,7; Years: 2002,2005

For some reason when I pull the values back out to the form, the months are pre-selecting in the listbox fine, but the years are not.

Any ideas?


EDIT - Additional code samples:

Controller - Manage

public ActionResult Manage(Guid id)
    {
        var list = _listService.GetList(id);

        var model = LoadModelFromObject(list);
        model.TimeframeMonths = GenerateMonthDropdown();
        model.TimeframeYears = GenerateYearDropdown(model.IncludeGuestsArrivedInTimeframeYears.Split(','));
        model.DaysOfWeek = GenerateDaysOfWeekDropdown();

        return View(model);
    }

Controller - 'Helper'

private IList<SelectListItem> GenerateYearDropdown(string[] selected)
    {
        var list = new List<SelectListItem>();

        var startYear = DateTime.Now.Year - 10;

        for (int idx = startYear; idx < startYear + 11; idx++)
        {
            list.Add(new SelectListItem
                         {
                             Value = idx.ToString(),
                             Text = idx.ToString(),
                             Selected = selected != null && selected.Contains(idx.ToString())
                         });
        }

        return list;
    }

View

@Html.CheckBoxFor(m => m.IncludeGuestsArrivedInTimeframe)
@Html.LabelFor(m => m.IncludeGuestsArrivedInTimeframe)
@Html.ListBoxFor(m => m.IncludeGuestsArrivedInTimeframeMonths, Model.TimeframeMonths)
@*@Html.ListBoxFor(m => m.IncludeGuestsArrivedInTimeframeYears, Model.TimeframeYears)*@
@Html.ListBox("IncludeGuestsArrivedInTimeframeYears", Model.TimeframeYears)
4
  • What does Model.TimeframeYears return? I mean the values. It must return type of IEnumerable<SelectListItem> but I cannot see what values it has. Commented Jan 4, 2012 at 15:28
  • @tugberk The Model.TimeframeYears has the IList<SelectListItem> and the Value and Text of each SelectListItem are the year (2002) Commented Jan 4, 2012 at 15:46
  • Could you provide sample values illustrating the problem of the IncludeGuestsArrivedInTimeframeYears and TimeframeYears properties? Commented Jan 4, 2012 at 17:45
  • See my DDL tutorials asp.net/mvc/tutorials/javascript/… and blogs.msdn.com/b/rickandy/archive/2012/01/09/… Commented Feb 14, 2012 at 19:54

3 Answers 3

4

You need to set Selected property of SelectItemList class to true for the options which you want to be pre-selected.

Example:

@{
    var foo = new List<SelectListItem> { 
        new SelectListItem { Text = "Foo 1", Value = "1", Selected = true },
        new SelectListItem { Text = "Foo 2", Value = "2" },
        new SelectListItem { Text = "Foo 3", Value = "3", Selected = true }
    };
}

@Html.ListBox("foo", foo)

In this case, Foo 1 and Foo 3 should appear as pre-selected. The above code generates the below html markup:

<select id="foo" multiple="multiple" name="foo">
    <option selected="selected" value="1">Foo 1</option>
    <option value="2">Foo 2</option>
    <option selected="selected" value="3">Foo 3</option>
</select>

Edit:

First of all, replace this code:

list.Add(new SelectListItem {
     Value = idx.ToString(),
     Text = idx.ToString(),
     Selected = selected != null && selected.Contains(idx.ToString())
});

with this code:

list.Add(new SelectListItem {
     Value = idx.ToString(),
     Text = idx.ToString(),
     Selected = true
});

Then run the app. If all the options are pre-selected, then I bet that this selected != null && selected.Contains(idx.ToString()) does not satisfy the condition.

Sign up to request clarification or add additional context in comments.

4 Comments

Okay, I changed it up a little bit. I have a method called GenerateYearDropdown which I modified to take an array of strings, which I pass in. The array is being passed in correctly, and setting the selected value of each list item, but it's not displaying those selections on the form.
@mmillican did you try out the above code? It works on my machine and should work on yours, too. The problem is with your code, post it as well.
I updated it and set Selected = true for all the entries and it's still not selecting them. Any other ideas? Sorry for the hassle!
Looks like they're not being selected. I was hoping to be able to send it to the view from the controller but maybe I won't be able to do that. Thx!
1

Another way of doing it

@Html.ListBox("categoryId", new MultiSelectList(ViewData["categories"] as System.Collections.IEnumerable, "Id", "CategoryName", Model.tIdx_ProductCategories.Select(x => x.CategoryId).AsEnumerable()))

Explanation:

  1. categoryId - would be name of control, when rendered as html
  2. ViewData["categories"] - is list of categories with Id and CategoryName properties
  3. Model.tIdx_ProductCategories carries the list of category ids to be selected in list box.

Comments

0

As it seems (e.g. here Preselect Items in Multiselect-Listbox (MVC3 Razor)) the Razor engine happily ignores the Selected property and compares the list from the model and the supplied option list by calling ToString() on the objects from the model and using string comparison to select.

What I cannot explain to myself is why this behavior is used with Html.ListBox(), which does not use any model and expects a collection of SelectListItem.

Think it's a bug, but it does not seem to have been addressed recently.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.