19

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?

4 Answers 4

23

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.

0
17

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>();
}
11
  • I get "Object reference not set to an instance of an object." because Model is null.
    – piris
    Commented Nov 29, 2013 at 8:17
  • You need to put your model reference in the view at the top i.e. @model ItemViewModel
    – hutchonoid
    Commented Nov 29, 2013 at 8:27
  • I'm not sure I understand...My option.cshtml view has model IEnumerable<Option> at the top. And Item.cshtml has model.ItemViewModel at the top.
    – piris
    Commented Nov 29, 2013 at 8:32
  • You need to initialize the collection too, if you are not sending any out on the initial load. Please see my updated qutestion above. :D
    – hutchonoid
    Commented Nov 29, 2013 at 8:32
  • You do need to send the model back to the view like this in your controller: public ActionResult Index() { ItemViewModel model = new ItemViewModel(); model.itemId = 1; model.Options = new List<Option>() { new Option { Text = "one" }, new Option { Text = "two" } }; return View(model); }
    – hutchonoid
    Commented Nov 29, 2013 at 8:35
0

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!

-3

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

1
  • 3
    No, you don't want to use the Model property, you want to give MVC an expression from which it will be able to determine the path of the properties to bind the view model.
    – billy
    Commented May 16, 2016 at 16:46

Not the answer you're looking for? Browse other questions tagged or ask your own question.