EditorFor() for a List of Complex Type (MVC)

31,335

Solution 1

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>();
}

Solution 2

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.

Share:
31,335
piris
Author by

piris

Updated on July 09, 2022

Comments

  • piris
    piris almost 2 years

    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?

  • piris
    piris over 10 years
    I get "Object reference not set to an instance of an object." because Model is null.
  • hutchonoid
    hutchonoid over 10 years
    You need to put your model reference in the view at the top i.e. @model ItemViewModel
  • piris
    piris over 10 years
    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.
  • hutchonoid
    hutchonoid over 10 years
    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
    hutchonoid over 10 years
    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); }
  • piris
    piris over 10 years
    Still working on it :( I do bind that data using AJAX with Kendo UI Wrappers and it looks like there is a limitation on their end. Not sure what else to think.
  • user3281466
    user3281466 about 9 years
    not working for me - gives me an error as soon as I try to add @model IEnumerable<Option>
  • hutchonoid
    hutchonoid about 9 years
    @user3281466 Sorry this was back in 2013
  • billy
    billy almost 8 years
    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.
  • Nerf
    Nerf almost 8 years
    It throws NULL reference at (var option in Model). i know it's empty but I need to create items for this list so I need only display inputs for it. How to do it?
  • hutchonoid
    hutchonoid almost 8 years
    @Nerf I'd use DisplayTemplates instead for just displaying data i.e. DisplayTemplates\Option.cshtml then @Html.DisplayFor(model => model.Options)
  • Asger Vestbjerg
    Asger Vestbjerg over 7 years
    @Nerf Did you fix the issue? I have this problem right now.