Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically add items to my collection from a view when single partial requires multiple objects?

I have a list of items displayed in my view. I need to be able to manually add items to this list from the UI with an add button. I know I need to load a partial view with javascript to get the new item to be displayed.

@{var count = 0;}
@foreach (var dx in Model.Patient.DxList)
{    
    <div class="form-field">
        <label>@(++count)</label>
        @Html.HiddenFor(d => dx.DxIndex)
        @Html.TextBoxFor(d => dx.Dx, new { @class = "small" })
        <span class="description">@((dx.DxRef != null) ? dx.DxRef.Title : "")</span>
        @Html.DropDownListFor(d=> dx.Indicator, new SelectList(Model.Codes, "Value", "Description", dx.Indicator), "Please select", new { @class = "" })
    </div>
}

However, because my item contains both a TextBox and a DropDownList, which is populated with Codes, does my partial view need a ViewModel too? To contain not only the Dx, but the list of appropriate Codes to create the list?

public class DxSingleViewModel
{
    public Dx Dx { get; set; }
    public List<Code> Codes { get; set; }
}

No idea if this is the general approach, or if I'm off base.

like image 518
Chace Fields Avatar asked Nov 04 '22 10:11

Chace Fields


1 Answers

You should separate the rendering of one item to a separate partial view / editor template and call it inside your foreach loop, so you have jsut one place where you define the markup for one item:

@foreach (var dx in Model.Patient.DxList)
{
    @Html.EditorFor(m => dx)
}

Then your AddNewItem action can return a partial view which just calls @Html.EditorForModel()

When adding and removing rows dynamically, you should embed your own index (for example a guid string) to the items to avoid collisions. Take a look at this great article which explains how to implement this with a custom html helper: http://blog.stevensanderson.com/2010/01/28/editing-a-variable-length-list-aspnet-mvc-2-style/

Your EditorTemplate will look like this:

@using (Html.BeginCollectionItem("DxList"))
{
    @Html.TextBoxFor(d => dx.Dx, new { @class = "small" })
    ....
}

Regarding your question about whether the viewmodel should contain the list for your dropdown or not: The viewmodel should contain every data you need to render the view. So i would say yes, its a good place to pass the list to the view.

Of cause you could pass it in the viewbag too, but i'm a friend of strong typed data bags, so i would prefer the viewmodel.

like image 62
Jan Avatar answered Nov 12 '22 14:11

Jan