I'm building a very simple form to edit the properties of an object. One of the properties is a list of other objects that are associated with it, so I'm using a two-list system: on the left, a list of currently associated objects, and on the right, a list of objects that are available to add; Add and Remove buttons underneath apply the relevant operations to the highlighted items in the relevant lists. Simple enough.
It's all working fine, except for one thing: when the page loads, all items in both lists are selected, even when I specifically set Selected = false when creating the items with which to populate the lists. This means that if the user submits the form without touching the lists, everything in the "current" list is removed, and everything in the "available" list is added. As they're multi-select listboxes, there's no dummy option for the user to select, so this issue is forcing them to always remove at least one of the current items and add at least one of the available items. Even if there were a dummy item, it forces the user to go and select it, and if they forget, their lists get messed up.
[Edited to add:]
An example of what the controller method is doing:
[HttpGet]
public ActionResult EditForm(int objectId)
{
MyObject objectToEdit = _objectStore.GetObject(objectId);
ObjectEditViewModel viewModel = new ObjectEditViewModel();
viewModel.Object = objectToEdit;
viewModel.AssociatedItemSelectList = objectToEdit.AssociatedItems.Select(o => new SelectListItem { Text = o.Name, Value = o.Id, Selected = false });
viewModel.AvailableItemSelectList = _itemStore.GetAllItems().Where(o => !objectToEdit.AssociatedItems.Contains(o))
.Select(o => new SelectListItem { Text = o.Name, Value = o.Id, Selected = false });
return View(viewModel);
}
...and the view just has
@Html.ListBoxFor(m => m.ItemsToAdd, Model.AvailableItemSelectList)
and
@Html.ListBoxFor(m => m.ItemsToRemove, Model.AssociatedItemSelectList)
in the relevant places. When the page loads, every option in the select listboxes has the form:
<option selected="selected" value="281">Example Item</option>
How are the items being selected between the creation of the list and the rendering of the page? How do I stop it? Or, failing that, how can I de-select them immediately on page load so that it appears to the user as if they start unselected? I have a fix that will make the page look like it should, but I'd like to get to the root of this problem.
This might be a late reply, but I think the reason has something to do with the binding of the listbox to the object it is referencing. For instance if you were to use ListBox instead of ListBoxFor and give ListBox a name so that it doesn't bind to anything, the items in the listbox won't be selected initially. But if you were to give it a name that would cause it to be bound the items will be selected. I was having the same trouble as you were and just happened to come across this through trial and error :-)
I had the same issue and realized that it was in my model property that I was setting the selected item(s) to all. It is hard without seeing your model to know what's going on, but check your definition of ItemsToAdd and AvailableItemSelectList and respectively for the other list and make sure you are not doing any .Select...ToList() there.
public List<SelectListItem> AvailableItemSelectList{
get
{
var items = //get your items from repository
return items;
}
}
public List<string> ItemsToAdd{
get{ //make sure you are not setting anything here}
set{}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With