Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a view model for a populated drop down list in ASP.NET MVC 3

I'm trying to teach myself MVC3. Im converting from webforms.

I need to create a view model that includes a dropdown list that I can pass to the controller and eventually render in the View.

How can I accomplish this? I have the skeleton but I dont know what the code is to actually create the name value pairs for the view.

namespace DH.ViewModels
{
    public class SharedLayoutViewModel
    {
        public IEnumerable<SelectListItem> Products
        {
            //some code to setup the value/name pairs to be rendered in the view.
            //example: 
            //<option value="1">Mustard</option>
            //<option value="2">Ketchup</option>
            //<option value="3">Mayo</option>
            //<option value="4">Relish</option>
            //<option value="5">BBQ</option>
         }
     }
  }

Thanks

like image 478
Maddhacker24 Avatar asked Mar 27 '12 02:03

Maddhacker24


2 Answers

I would create a class for Product and the create Products Property in my main viewmodel which is of type List

public class ProductViewModel
{
  public int ID { set;get;}
  public string Name { set;get;}
}

public class OrderViewModel
{
  public int OrderNumber { set;get;}
  public List<ProductViewModel> Products { set;get;}
  public int SelectedProductId { set;get;}    
}

and in your Controller Action method

public ActionResult Order()
{     
   var orderVM=new OrderViewModel();
   //Items hard coded for demo. You may replace with values from your db
   orderVM.Products= new List<ProductViewModel>
    {
        new ProductViewModel{ ID=1, Name="IPhone" },
        new ProductViewModel{ ID=2, Name="MacBook Pro" },
        new ProductViewModel{ ID=3, Name="iPod" }           
    };
   return View(orderVM);
}

and in your view which is strongly typed to OrderViewModel.

@model ORderViewModel
@using (Html.BeginForm())
{
  <p> 
    @Html.DropDownListFor(x => x.SelectedProductId ,
                     new SelectList(Model.Products, "ID", "Name"), "-- Select Product--")
  </p>
  <input type="submit" />
}

I have added a SelectedProductId property also, so you will get the user selected value from the dropdown in that Property when user post the form back to the controller.

You can also use the generic SelectListItem type collection as your view model property to transfer the dropdown data instead of your custom ProductViewModel collection.

public class OrderViewModel
{
  public int OrderNumber { set;get;}
  public List<SelectListItem> Products { set;get;}
  public int SelectedProductId { set;get;}    
}

and in the GET action,

public ActionResult Order()
{     
   var orderVM=new OrderViewModel();
   //Items hard coded for demo. You may replace with values from your db
   orderVM.Products= new List<SelectListItem>
    {
        new SelectListItem {Value = "1", Text = "IPhone"},
        new SelectListItem {Value = "2", Text = "MacBook"},
        new SelectListItem {Value = "3", Text = "Candy"}
    };
   return View(orderVM);
}

And in your view,

@Html.DropDownListFor(x => x.SelectedProductId, Model.Products, "-- Select Product--")

EDIT : As per the request from OP, edited the answer to have the Property returning static items as products

I added a get implementation to Products property to return a list of static products.

public class OrderViewModel
{
        private List<ProductViewModel> _products;
        public int OrderNumber { set; get; }
        public List<ProductViewModel> Products
        {
            get
            {
                if (_products == null)
                {
                    _products = new List<ProductViewModel>();
                    _products.Add(new ProductViewModel { ID = 1, Name = "Ketchup" });
                    _products.Add(new ProductViewModel { ID = 1, Name = "Mustard" });
                    _products.Add(new ProductViewModel { ID = 1, Name = "Relish" });
                    _products.Add(new ProductViewModel { ID = 1, Name = "Mayo" });
                }
                return _products;
            }
        }
       public int SelectedProductId { set;get;}
}

Now in your controller, you don't need to call the GetAvailableProductsmethod as it is already there. So the controller will looks like this.

    public ActionResult Order()
    {
        OrderViewModel orderVM = new OrderViewModel();           
        return View(orderVM);
    }

Here is the output. enter image description here

If you have many items in the products, move it to a method and call that method int he get implementation instead of writing that there. That is much cleaner approach.

like image 87
Shyju Avatar answered Nov 15 '22 19:11

Shyju


I prefer to do it this way.

@Html.DropDownListFor(m => m.ProductId, new SelectList(Model.Products, "ID", "Name"))

So my view model just contains a list of products and generate the select list on the view.

like image 6
lahsrah Avatar answered Nov 15 '22 19:11

lahsrah