0

I have a partial view that I would like the client to make selections in using check-boxes. Then I want the Ids of the selected items sent to the controller when a submit button is clicked. The controller will redirect to a verification view. What would be a good,simple, and safe solution? I would like to avoid Javascript if possible. Thanks!

VIEW

@model OrderTracking.Models.ViewModel.ItemDataView

<div>

@using (Html.BeginForm("VerifyItem", "ReserveItem", FormMethod.Get))
{
    //@Html.AntiForgeryToken()  //TODO: Wire-up
    <table class="table table-striped table-condensed table-hover">
        <thead>
            <tr>
                <th></th>
                <th>Item ID</th>
            </tr>
        </thead>
        <tbody>

            @foreach (var i in Model.ItemProfile)
            {
                <tr>
                    <td>@Html.CheckBoxFor(r => i.IsSelected, new { @class = "checkbox" })</td>
                    <td>@Html.DisplayFor(r => i.ItemId)</td>

                </tr>
            }
        </tbody>
    </table>



    @Html.ActionLink("Verify Order Information", "VerifyOrderInfo", "ReserveItem", "", new { @class = "btn btn-primary btn-large" } ) 

}

MODEL

namespace OrderTracking.Models.ViewModel
{
public class ItemProfileView
{
    [Key]
    public int ItemId { get; set; }
    public bool IsSelected { get; set; }

}

public class ItemDataView
{
    public IEnumerable<ItemProfileView> ItemProfile { get; set; }
}

}

CONTROLLER

    public ActionResult VerifyOrderInfo()  
    {

        return View();

    }
Stormseye
  • 25
  • 7
  • You cannot use a `foreach` loop - refer [this answer](http://stackoverflow.com/questions/30094047/html-table-to-ado-net-datatable/30094943#30094943) for binding to collections (and you will need to include a hidden input for the `ItemId` property –  Jan 22 '17 at 03:41
  • Thanks for the link. That's really helpful info. – Stormseye Jan 22 '17 at 09:33

1 Answers1

1

There are many ways to do this. One that requires the least changes to your code would be to:

  • Change your form to a Post and action to VerifyOrderInfo

    @using (Html.BeginForm("VerifyOrderInfo", "ReserveItem", FormMethod.Post))

  • Change IEnumerable to a List so you can bind by index

    public List<ItemProfileView> ItemProfile { get; set; }

  • Now you can reference the checkbox by index and add a hidden input for ItemId

    @Html.CheckBoxFor(r => r.ItemProfile[i].IsSelected, new { @class = "checkbox" }) @Html.HiddenFor(r => r.ItemProfile[i].ItemId)

  • Use a submit button instead of an ActionLink

    <input type="submit" name="Verify Order Information" class="btn btn-primary btn-large" />

  • Add the model into the VerifyOrderInfo action so you can code against it

    public ActionResult VerifyOrderInfo(ItemDataView model)

Now when you submit the form it should send the model into the action with an ItemProfile list populated with ItemId and IsSelected form the input items.

fcs
  • 78
  • 1
  • 1
  • 7
  • Refreshing answer. Simple, step-by-step, and not at all cryptic. Everything seems to work except I'm having trouble getting the view to call the VerifyOrderInfo controller instead of the default ReserveItem controller, but I'll get into that tomorrow. Thanks so much! – Stormseye Jan 22 '17 at 09:38
  • The code is trying to call the ReserveItem controller. The action comes first in `BeginForm("{action}", "{controller}",...)` – fcs Jan 23 '17 at 15:14
  • I'm sorry. I misspoke. I meant to say that it is calling ReserveItem GET action instead of the VerifyOrderInfo POST action. Both actions are in the ReserveItem controller. I do have a VerifyOrderInfo view made.If I attempt to type in the path directly into the address bar, I get a "Server Error in / Application - The resources or one of its dependencies cannot be found." However, if i change the ViewOrderInfo action to Get instead of Post, it will load the page template (of course, not with any data). – Stormseye Jan 24 '17 at 00:52
  • I found the problem. This form is part of a partial view. I was using a javascript load function to call the partial view, and that call was being made from within another form which was defaulting to the GET method. Ugh. Thanks again for the great answer. – Stormseye Jan 24 '17 at 02:55