Search code examples
c#listboxentity-framework-6.1asp.net-mvc-5.2

Get selected values of a ListBox


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.


Solution

  • 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".