Get selected values of a ListBox

1.3k views Asked by At

Model:

public virtual ICollection<Product> OriginalProducts { get; set; }
public virtual ICollection<Product> SimilarProducts { get; set; }

View (Create and Edit are equal):

<div id="divSimilar" class="form-group">
    @Html.Label("Similar Products", htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.ListBox("Products", null, htmlAttributes: new { @class = "form-control" })
    </div>
</div>

Controller:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "MyAttributes")] Product product)
{
    if (ModelState.IsValid)
    {
        db.Products.Add(product);
        List<string> selectedSimilars = Request.Form.GetValues("Products").ToList();

        foreach (string Id in selectedSimilars)
        {
            Product similarProd = db.Products.Find(System.Convert.ToInt32(Id));
            if (similarProd != null)
                product.SimilarProducts.Add(similarProd);
        }

        db.SaveChanges();
        return RedirectToAction("Index").Success("Successfully created");
    }

    ViewBag.Products = new SelectList(db.Products, "Id", "Name", product.SimilarProducts);
    return View(product);
}

public ActionResult Edit(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    Product product = db.Products.Find(id);
    if (product == null)
    {
        return HttpNotFound();
    }
    ViewBag.Products = new SelectList(db.Products.Where(p => p.Id != product.Id), "Id", "Name", product.SimilarProducts);
    return View(product);
}

So, since "Create" part is working fine, I want to know how can I make to get all selected SimilarProducts (that I added in "Create") in my "Edit" view. What changes are necessary in controller to make it work?

Btw, since I'm using the ListBox, I think there's a different way of the DropDownList, because I used this way for all my DropDownLists and are working fine.

EDIT

I want to display in "Edit" view, all products (that were selected when I created that product) in blue. In other words, the ActionResult "Edit" should get all selected products from the SimilarProducts list, as in the DropDownList.

2

There are 2 answers

0
developer033 On BEST ANSWER

Finally I managed to make it work, I'll post the solution, in case of anyone needs in the future:

ViewBag.Products = new MultiSelectList(db.Products.Where(p => p.Id != product.Id), "Id", "Name", product.SimilarProducts.Select(p => p.Id));

Little explanation:

Since I'm using ListBox, so I must use MultiSelectList, because SelectList recognizes just one item selected, its parameter is: (object selectedValue), already on MultiSelectList is: (IEnumerable selectedValues), so I changed SelectList to MultiSelectList and added it: .Select(p => p.Id)) into my ActionResult "Edit".

4
Alexander Bell On

ListBox Control may have multiple selected Items (thus, multiple different values) as demonstrated in the following code snippet (re: https://msdn.microsoft.com/en-us/library/system.windows.controls.listbox.selecteditems%28v=vs.110%29.aspx)

private void SelectedItems(object sender, RoutedEventArgs e)
{
    if (lb.SelectedItem != null)
    {
        label1.Content = "Has " + (lb.SelectedItems.Count.ToString()) + " item(s) selected.";
    }
}

You should specify the business logic for finding the Item in the selection (e.g., first in the selection). But, if selection mode is set to Single you may use the property SelectedItem.

Hope this may help.