1

I have a model with 2 views: Create.chtml (with @model Model1 for adding new data) Index.chtml (with @model IEnumerable to loop through list to view current data).

I want to have both adding and listing functionality in 1 view. How can I do this since I can only have 1 model statement in a view? Also, this is not 2 different models, it's the same one.

Thanks.

gibsonsg
  • 35
  • 2
  • 11

1 Answers1

1

You create a new view model with properties for your list and for adding new item,

public class CustomerListViewModel
{
   public List<Customer> CustomerList { set;get;}  // For showing the existing list

   // The below properties are for adding new customer
   public string NewCustomerName { set;get;}
   public string NewCustomerEmail { set;get;}
}
public class Customer
{
   public string Name { set;get;}
}

Now in your GET action, create an object of this, load the CustomerList property and send it to view

public ActionResult Index()
{
  var vm = new CustomerListViewModel();
  //Hard coding 2 customers for demo. you may replace with data from db
  vm.CustomerList= new List<Customer> {
                                        new Customer  { CustomerName ="Scott"},
                                        new Customer  { CustomerName ="John"},
  };
  return View(vm);
}

Now your view will be strongly typed to this new view model

@model CustomerListViewModel
<h2>Existing customers</h2>
@foreach(var c in Model.CustomerList)
{
  <p>@c.Name</p>
}
<h3>Add new customer</h3>
@using(Html.BeginForm("Add","Customer"))
{
  @Html.LabelFor(s=>s.NewCustomerName)
  @Html.TextBoxFor(s=>s.NewCustomerName)

  @Html.LabelFor(s=>s.NewCustomerEmail)
  @Html.TextBoxFor(s=>s.NewCustomerEmail)
  <input type="submit" />
}

And in your Add HttpPost action, you can use the same view model as the parameter

[HttpPost]
public ActionResult Add(CustomerListViewModel model)
{
  var name = model.NewCustomerName;
  var email = model.NewCustomerEmail;
  // Save this
  // to do  :Return something (Redirect to success page)
}
Shyju
  • 214,206
  • 104
  • 411
  • 497
  • Suggestion: instead of populating the properties why not just include one property of the object. like `public class CustomerListViewModel { public List CustomerList { set;get;} public Customer NewCustomer {get;set;} }` Just a thought. – Nkosi Apr 12 '16 at 15:41
  • Then you need to manipulate the form control name's so that model binding works. This is the reason **i personally** prefer lean - flat view models. Well, that is y they are called "View Models" , they are specific to the view. – Shyju Apr 12 '16 at 15:42
  • 1
    I understand your thinking on that. – Nkosi Apr 12 '16 at 15:44