I'm trying to create an EditorFor() for a List of a Complex Type. Specifically the "Options" below should get displayed in a one multitext input where each option(string) is in a new line. However, I can only display one option in a textbox and not all options....
My View Model and Class:
public class ItemViewModel
{
public int itemId { get; set; }
[UIHint("Option")]
public List<Option> Options { get; set; }
}
public class Option
{
public string Text { get; set; }
}
My Editor Templates:
EditorTemplates\Item.cshtml
@model ItemViewModel
@Html.EditorFor(model => model.Options)
EditorTemplates\Option.cshtml
//Not sure how to dispay the options here
<textarea rows="4" cols="50">
Display Options
</textarea>
If I update my EditorTemplates to:
EditorTemplates\Item.cshtml
@model ItemViewModel
@Html.EditorFor(model => model.Options[0])
EditorTemplates\Option.cshtml
@Html.TextBoxFor(x => x.OptionText)
It will display the first option in a textbox. But, again what I'm trying to achieve is to display all options in a multitext input.
Any ideas?
You nearly have it.
In this EditorTemplates\Option.cshtml
add the following:
@model IEnumerable<Option>
@foreach(var option in Model)
{
@Html.TextBoxFor(m => option.Text)
}
Then call it in your view like this:
@Html.EditorFor(model => model.Options)
If you are not populating your options on the initial get, you will need to add this in your ItemViewModel class:
public class ItemViewModel
{
public ItemViewModel()
{
Options = new List<Option>();
}
public int itemId { get; set; }
[UIHint("Option")]
public List<Option> Options { get; set; }
}
This constructor initializes the collection:
public ItemViewModel()
{
Options = new List<Options>();
}
Just create a view in Shared/EditorTemplates/Option.cshtml
@model Option
@Html.TextBoxFor(m => m.Text)
And call
@Html.EditorFor(model => model.Options)
EditorFor iterates over collection for you.
I bumped into the same issue and I have different solution but a bit similar with hutchonoid.
So the first part is same, modify the Option.cshtml like following:
@model IEnumerable<Option>
@foreach(var option in Model)
{
@Html.TextBoxFor(m => option.Text)
}
And in Item.cshtml, I call the Option.cshtml using Html.Partial, like following:
@Html.Partial("Option", model:Model.Options)
And in my case, I don't have to modify the ItemViewModel class.
Hopefully this can be alternative answer for this problem.
Cheers!
Using @hutchonoid's answer, you should call the template in view:
@Html.EditorFor(model => Model.Options)
instead of
@Html.EditorFor(model => model.Options)
and please be noted, the Option.cshtml
template is in
Views\Item\EditorTemplates\Option.cshtml
or View\Shared\EditorTemplates\Option.cshtml