Search code examples
asp.net-mvcbootstrap-multiselect

Unable to display MultiSelectList.SelectedValues on MVC view


I am working with a MVC application that is legacy code. So far, the changes I made are the 2 calls to retrieve the lists of AccountDivisionModel objects. The original code called the stored procedures and returned an ObjectResult, which contained the data.

public class AccountDivisionModel
{
    int DivisionID;
    string DivisionName;
    int AccountID;
    bool IsActive;
}

I'm making 2 calls to retrieve a list of divisions that belong to an account and a list of (selected) divisions that belong to a contact of the account.

var aDivs = Account.GetDivisionByAccountID(c.AccountID).ToArray();
var cDivs = Contact.GetDivisionByContactID(c.ContactID).ToArray();
ViewBag.AccountDivisions = new MultiSelectList(aDivs, "DivisionID", "DivisionName", cDivs);

In my Edit view

@Html.DropDownList("AccountDivisions", null, htmlAttributes: new { @class = "form-control", @multiple = "multiple", @placeholder = "Select Division(s)" })

I don't know why the SelectedValues is not showing even though when I click on the text box (@placeholder), I can see it populate the drop down list with all divisions.

What have I done wrong?

Below is the image of the current working interface. As you can see, the Selected Values displayed in the box and the drop down list showing the remaining items that have not been selected.

image of the current working interface


Solution

  • The 4th argument of MultiSelectList needs to a collection of the selected values (usually int or string) which match the type of the second parameter. Currently you are passing it a collection of complex objects so it does not match any option value. Your could solve this by changing

    var cDivs = Contact.GetDivisionByContactID(c.ContactID).ToArray();
    

    to

    var cDivs = Contact.GetDivisionByContactID(c.ContactID).Select(c => c.DivisionIDs);
    

    However I would recommend including a property in your model representing the selected divisions that allows 2 way binding

    Model

    public IEnumerable<int> SelectedDivisions { get; set; }
    

    Controller

    model.SelectedDivisions = Contact.GetDivisionByContactID(c.ContactID).Select(c => c.DivisionID);
    ViewBag.AccountDivisions = new MultiSelectList(aDivs, "DivisionID", "DivisionName"); // 4th parameter not required
    

    View

    @Html.ListBoxFor(m => m.SelectedDivisions, (MultiSelectList)ViewBag.AccountDivisions, new { @class = "form-control"}) // ListBoxFor adds multiple attribute
    

    The model then contains the selected values on post back.