MikeHe
MikeHe

Reputation: 68

Displaying list of objects in mvc with handlebars

I have a model that has a list of objects as one of its properties, and I'm trying to figure out how to get them to post correctly. It's a jQuery Mobile project with MVC 4, but I'm trying to figure out if Handlebars is the way to go for displaying the list, or if there's a way to use html helpers.

What's happening is the user will select how many children they have, and for each child there needs to be a dropdown for the age, and a checkbox for tobacco use if they're 18 or older. I have two classes, Person and Child to encapsulate this data with the only difference between them is the age ranges.

Here's the Handlebars approach:

<script type="text/x-handlebars-template" id="ChildTemplate">

         <div class="childWrapper">
            <label for="Children[{{id}}].Age">Child Age:</label>
            <select name="Children[{{id}}].Age" id="Children[{{id}}].Age" class="childDropdown">
                <option>0</option>
                <option>1</option>
                <option>2</option>
                <option>3</option>
                <option>4</option>
                <option>5</option>
                <option>6</option>
                <option>7</option>
                <option>8</option>
                <option>9</option>
                <option>10</option>
                <option>11</option>
                <option>12</option>
                <option>13</option>
                <option>14</option>
                <option>15</option>
                <option>16</option>
                <option>17</option>
                <option>18</option>
                <option>19</option>
                <option>20</option>
                <option>21</option>
                <option>22</option>
                <option>23</option>
                <option>24</option>
                <option>25</option>
            </select>

            <div class="childSmoker">
                <label for="Children[{{id}}].Smoker">Tobacco User?</label>
                <input type="checkbox" name="Children[{{id}}].Smoker" id="Children[{{id}}].Smoker" />
                <input type="hidden" name="Children[{{id}}].Smoker" value="false" />

            </div>
        </div>

    </script>

This works for adding and submitting a variable amount of children, but when posting, the checkbox values are always false, and I haven't been able to figure out a way around that. I've tried it with and without the hidden field, but I can't seem to connect to the checkbox change event, I think jQuery Mobile is interfering in some way.

The other way I tried was creating an editor template that has a model that is the list of Child objects, but I keep getting a runtime error. Here is the code in the template.

<script type="text/x-handlebars-template" id="ChildTemplate">
    <div class="childWrapper">
        @Html.EditorFor(m => m.Children)
    </div>
</script>

Here is the template I created. It's under Shared/EditorTemplates/Child.cshtml

@model List<MyCompany.Models.Child>

@foreach(var c in Model)
{
@Html.LabelFor(m => c.Age)
@Html.DropDownListFor(m => c.Age, c.Ages)

@Html.LabelFor(m => c.Smoker)
@Html.CheckBoxFor(m => c.Smoker)
}

The error it's giving me is: The model item passed into the dictionary is of type 'PreferredOneMobileMVC.Models.Child', but this dictionary requires a model item of type 'System.Collections.Generic.List`1. I haven't been able to figure out how to get around it other than making it an editor for a single instance, but that gets me right back to where I started. Here is the model that the page is initially binding to:

    public Person Self  { get; set; }
    public Person Spouse { get; set; }
    public List<Child> Children { get; set; }
    public string County { get; set; }

    [Display(Name = "Coverage Begin Date:")]
    public virtual string CoverageDate { get; set; }

    [Display(Name = "Covered Members:")]
    public virtual string CoverageSelection { get; set; }


    public SelectList EffectiveDates { get; set; }


    public SelectList CoveredMembers { get; set; } 

    public SelectList Counties { get; set; }

I think if I can't use an editor template the next best solution would be to figure out how to use the handlebars syntax with html helpers. My initial approach was

@html.LabelFor(m => m.Children[{{id}}].Age)
@Html.DropDownListFor(m => m.Children[{{id}}].Age, Model.Children[{{id}}].Ages)

but the html helpers don't want to work with Handlebars and I can't get it to build. Any suggestions on the best approach to take? Thanks.

Upvotes: 0

Views: 1659

Answers (1)

MikeHe
MikeHe

Reputation: 68

I got it figured out. If I use helpers in the template that don't use lambdas it works. Here's the new template.

<script type="text/x-handlebars-template" id="ChildTemplate">

     @Html.Label("p[{{id}}].Age")
    <select name="p[{{id}}].Age" id="p[{{id}}].Age">
        <option>1</option>
        <option>2</option>
        <option>3</option>
        <option>4</option>
    </select>
    <div>
        @Html.Label("p[{{id}}]].Smoker")
        @Html.CheckBox("p[{{id}}].Smoker")
    </div>

</script>

As long as I keep the id sequential I can add/remove as many as I like. My controller method accepts a List<Person> and everything is being posted correctly now.

Upvotes: 2

Related Questions