简体   繁体   中英

Passing model with list of checkboxes from view to controller

I am trying to pass model from View back to controller. I am passing NaborViewModel to View. It is a list of objects and every object has 4 checkboxes (some of them randomly checked).

Model:

public class NaborViewModel
{
    public List<WowClass> WowClasses { get; set; }
}

Actions:

    [HttpGet]
    public ActionResult Nabor()
    {
        NaborViewModel viewModel = new NaborViewModel();
        DatabaseDataContext context = new DatabaseDataContext();
        viewModel.WowClasses = context.WowClasses.ToList();

        return View(viewModel);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Nabor(NaborViewModel model)
    {
        //DB actions
        return RedirectToAction(Consts.ActionNabor);
    }

In view i have 2 forms each with different approach. The first one is the one i have created with thought it might work. The second form is approach i found online. The first one is displaying passed data correctly (filled checkboxes). The second one is even displaying every checboxes unchecked. When forms are submitted, they both returns null back to controller action.

View:

        @using (Html.BeginForm(Consts.ActionNabor, Consts.ControllerAdmin, FormMethod.Post))
        {
            @Html.AntiForgeryToken()
            <table class="admin-table">
                <thead>
                    <tr>
                        <th>Class</th>
                        <th>Status</th>
                        <th colspan="3">Požadované talenty</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var cls in Model.WowClasses)
                    {
                        <tr>
                            @Html.HiddenFor(x => cls.Id)
                            <td>@cls.ClassName</td>
                            <td>@Html.CheckBoxFor(x => cls.Open)</td>
                            <td style="text-align: left">@Html.CheckBoxFor(x => cls.NeedTalents1) <span>@cls.Talents1</span></td>
                            <td style="text-align: left">@Html.CheckBoxFor(x => cls.NeedTalents2) <span>@cls.Talents2</span></td>
                            <td style="text-align: left">@Html.CheckBoxFor(x => cls.NeedTalents3) <span>@cls.Talents3</span></td>
                        </tr>
                    }
                </tbody>
            </table>

            <input type="submit" value="@Consts.Submit" />
        }

        <div class="horizontal-line-both"></div>

        @using (Html.BeginForm(Consts.ActionNabor, Consts.ControllerAdmin, FormMethod.Post))
        {
            @Html.AntiForgeryToken()
            <table class="admin-table">
                <thead>
                    <tr>
                        <th>Class</th>
                        <th>Status</th>
                        <th colspan="3">Požadované talenty</th>
                    </tr>
                </thead>
                <tbody>
                    @for (int i = 0; i < Model.WowClasses.Count; i++)
                    {
                        <tr>
                            <td>
                                <input type="text" value="@Model.WowClasses[i].ClassName" name="Expense[@i].Id">
                            </td>
                            <td>
                                <input type="checkbox" value="@Model.WowClasses[i].Open" name="Expense[@i].Id">
                            </td>
                            <td>
                                <input type="checkbox" value="@Model.WowClasses[i].NeedTalents1" name="Expense[@i].Id">
                            </td>
                            <td>
                                <input type="checkbox" value="@Model.WowClasses[i].NeedTalents2" name="Expense[@i].Id">
                            </td>
                            <td>
                                <input type="checkbox" value="@Model.WowClasses[i].NeedTalents3" name="Expense[@i].Id">
                            </td>
                            <td>
                                <input type="hidden" value="@i" name="Expense[@i].Id">
                            </td>
                        </tr>
                    }
                </tbody>
            </table>

            <input type="submit" value="@Consts.Submit" />
        }

I got this to work with a combination of your two approaches. See the following:

@for (int i = 0; i < Model.WowClasses.Count; i++)
{
    ...
    <tr>
        @Html.EditorFor(model => model.WowClasses[i].Open)
    </tr>
    ...
}

Accessing each item in your List via its index is key. If you look at the HTML generated using this method, each item's name includes its index (in the example above, the generated input's name is this: name="WowClasses[0].Open" ). This is how your controller action can distinguish between list items.

For your second form, you can modifying every input field like this,

for check box,

<input type="checkbox" id="WowClasses_@(i)_Open" name="WowClasses[@i].Open" value="true" />

for input filed,

<input type="checkbox" id="WowClasses_@(i)_ClassName" name="WowClasses[@i].ClassName" value="true" />

you just changes your every input filed by your class property.hopefully this your help

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM