Reputation:
Theres links already on how to use multiple models for a view with different ways to do it, however, I tried those and could not get them to work, what am I doing wrong?
I simply want two form inputs in 1 view, and one model, but one of the form inputs uses a list<'model'> and the other uses 'model', here's what I mean:
UPDATE: copy/paste this code, if you select and submit any check box items you will get an error at @Model.input.passWord and I have no idea why, checkbox items wont show either, need help.
View (Index.cshtml):
@using stupidassTests.Models
@model MyViewModel
@{
ViewBag.Title = "Index";
}
<h2>Password Input</h2>
<div>
<p>Enter Password</p>
@using (Html.BeginForm("Index", "Home", FormMethod.Get))
{
@Html.TextBox("password")
<button type="submit" value="Search"></button>
}
<p>@Model.input.passWord</p> <!--passWord is underlined with red because it conflicts with the List'model'-->
</div>
<h2>Checkbox</h2>
<div>
@using (Html.BeginForm())
{
for (var i = 0; i < Model.inputCollection.Count; i++)
{
<p>
@Html.HiddenFor(n => n.inputCollection[i].Id)
@Html.DisplayFor(n => n.inputCollection[i].Name)
@Html.HiddenFor(n => n.inputCollection[i].Name)
@Html.CheckBoxFor(n => n.inputCollection[i].Checked)
</p>
}
<input id="Submit1" type="submit" value="submit" />
if (ViewBag.Values != null)
{
foreach (var item in ViewBag.Values)
{
<p>@item</p>
}
}
}
So as you can see, copy/paste my code and try to run it, 'password' form input is being shoved out by 'checkbox' input, it seems the two '@model' are conflicting under one model class, how do I fix this?
Controller (HomeController.cs):
public ActionResult Index() {
return View();
}
[HttpGet, ActionName("Index")]
public ActionResult PasswordInput(string password)
{
FormInputs pss = new FormInputs();
pss.passWord = password;
MyViewModel mvm = new MyViewModel() { input = pss, isList = false };
return this.View("Index", mvm);
}
[HttpGet]
public ActionResult CheckBoxGet()
{
var list = new List<FormInputs>
{
new FormInputs { Id = 1, Name = "Aquafina", Checked = false },
new FormInputs { Id = 2, Name = "Mulshi Springs", Checked = false },
new FormInputs { Id = 3, Name = "Alfa Blue", Checked = false },
new FormInputs { Id = 4, Name = "Atlas Premium", Checked = false },
new FormInputs { Id = 5, Name = "Bailley", Checked = false },
new FormInputs { Id = 6, Name = "Bisleri", Checked = false },
new FormInputs { Id = 7, Name = "Himalayan", Checked = false },
new FormInputs { Id = 8, Name = "Cool Valley", Checked = false },
new FormInputs { Id = 9, Name = "Dew Drops", Checked = false },
new FormInputs { Id = 10, Name = "Dislaren", Checked = false },
};
MyViewModel mvm = new MyViewModel() { inputCollection = list, isList = true };
return this.View("Index", mvm);
}
[HttpPost]
public ActionResult CheckBoxPost(List<FormInputs> list)
{
var selected = list.Where(x => x.Checked).Select(x => x.Name);
ViewBag.Values = selected;
MyViewModel mvm = new MyViewModel() { inputCollection = list, isList = true };
return this.View("Index", mvm);
}
Model (FormInputs.cs):
public class MyViewModel
{
public FormInputs input;
public List<FormInputs> inputCollection;
public bool isList;
}
public class FormInputs
{
public string passWord = "";
public int Id { get; set; }
public string Name { get; set; }
public bool Checked { get; set; }
public List<string> checkBox = new List<string>();
}
So just as a summary, because I'm a beginner at MVC, how do I re-work this code (btw copy/paste it) so that both form inputs can co-exist in 1 view?
Upvotes: 2
Views: 2119
Reputation: 1493
This might be a good example to use the Composite Pattern. You can have a ViewModel with two properties:
public class MyViewModel{
public FormInputs input;
public List<FormInputs> inputCollection;
public bool isList;
}
And arrange the data accordingly:
public ActionResult PasswordInput(string password)
{
FormInputs pss = new FormInputs();
pss.passWord = password;
MyViewModel mvm = new MyViewModel(){input = pss, isList = false}
return this.View("Index", mvm);
}
AND
public ActionResult CheckBoxGet()
{
var list = new List<FormInputs>
{
new FormInputs { Id = 1, Name = "Aquafina", Checked = false },
new FormInputs { Id = 2, Name = "Mulshi Springs", Checked = false },
new FormInputs { Id = 3, Name = "Alfa Blue", Checked = false },
new FormInputs { Id = 4, Name = "Atlas Premium", Checked = false },
new FormInputs { Id = 5, Name = "Bailley", Checked = false },
new FormInputs { Id = 6, Name = "Bisleri", Checked = false },
new FormInputs { Id = 7, Name = "Himalayan", Checked = false },
new FormInputs { Id = 8, Name = "Cool Valley", Checked = false },
new FormInputs { Id = 9, Name = "Dew Drops", Checked = false },
new FormInputs { Id = 10, Name = "Dislaren", Checked = false },
};
MyViewModel mvm = new MyViewModel(){inputCollection = list , isList = true}
return this.View("Index", mvm);
}
AND in view, use this:
@model MyViewModel
Check the isList
property before using the input/inputCollection
Upvotes: 1
Reputation: 14604
You can use viewmodel.
Use ViewModel
For view model you have to create a class and in this class you will define all models as properties of this class.Here are two classes.
public class EmployeeDetails
{
[Required]
[Display(Name = "Name")]
public string Name { get; set; }
}
public class Employee
{
public int Id { get; set; }
}
Here is viewmodel
public class ViewModel
{
public Employee emp { get; set; }
public EmployeeDetails empdet{ get; set; }
}
Now in Controller you will do like this
public ActionResult About()
{
ViewModel vm = new ViewModel();
vm.emp = new Employee();
vm.empdet = new EmployeeDetails();
return View(vm);
}
And in view you will receive it like this
@model ViewModel
Upvotes: 1