Unable to display MultiSelectList.SelectedValues on MVC view

1k Views Asked by At

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

2

There are 2 best solutions below

0
On BEST ANSWER

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.

1
On

you do not need the @ for all the HTML Attributes, you only need it for class , because that is a reserved word in c#

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

You may be doing this all wrong , the typical use for a DropDown is for users to choose one option out of a bunch of options. So Typically a Model will have 2 properities , something like:

List<SelectItems> Accounts
int SelectedAccount

then.. you would do

@Html.DropDownListFor( x => x.SelectedAccount, (SelectList)x.Accounts)