1

Can anyone please tell me how do I pass lists of selected relevant hidden field values from to controller. The assigned field return value is Boolean(true). There are over 100 list items. If admin person select(Assigned) list and submit, it'll pass all list values pass to the controller and update database.

This my view page chtml code:

@using (Html.BeginForm("CAssigned", "Orders", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @foreach (var item in Model)
    {
        @Html.HiddenFor(model => item.LocationId)
        <td>
            @Html.DisplayFor(modelItem => item.MapIcons)
            @Html.HiddenFor(model => item.MapIcons,"MapIcons")
        </td>
        <td>
            @Html.EditorFor(modelItem => item.Assigned)
            @Html.HiddenFor(model => item.Assigned)
        </td>
    } 
    <input type="Submit" value="Select" />
}

My controller

   [HttpGet]
    public ActionResult CAssigned()
    {
        var orders = db.Locations.ToList();
        return View(orders);
    }

    [HttpPost] 
   public ActionResult CAssigned(IEnumerable<Location>) 
    {
    return View();
    }

html view source

<input data-val="true" data-val-number="The field LocationId must be a number." data-val-required="The LocationId field is required." id="item_LocationId" name="item.LocationId" type="hidden" value="1" />
<td>
    red-dot.png
    <input Length="8" id="item_MapIcons" name="item.MapIcons" type="hidden" value="red-dot.png" /></td>
<td>
<input class="check-box" data-val="true" data-val-required="The Assigned to Courier field is required." id="item_Assigned" name="item.Assigned" type="checkbox" value="true" /><input name="item.Assigned" type="hidden" value="false" />
<input type="Submit" value="Select" />
<input id="item_Assigned" name="item.Assigned" type="hidden" value="False" />
<td>
leppie
  • 115,091
  • 17
  • 196
  • 297
Rob
  • 193
  • 5
  • 18
  • You cannot use a `foreach` loop to bind to a collection (you are generating duplicate `id` attributes (invalid html) and `name` attributes which have no relationship to your model (no indexers). Your need to use a `for` loop or a custom `EditorTemplate` for the model. In any case why do you have a hidden input for property `Assigned` which will be just ignored since you have an `EditorFor()` for the same property. And your POST method parameter needs to be your model (`public ActionResult CAssigned(IEnumerable)` since that's what your view is based on. –  May 11 '15 at 00:56
  • Thank you for your replay. The @for(var i = 1; i < number; i++) how can I set the numbers? – Rob May 11 '15 at 01:52
  • Your model needs to implement `IList` and then `for(int i = 0; i < Model.Count; i++) { @Html.HiddenFor(m => m[i].LocationId .... }` which will generate ``, `` etc. Refer also [this answer](http://stackoverflow.com/questions/30094047/html-table-to-ado-net-datatable/30094943#30094943) for more detail –  May 11 '15 at 01:55
  • Thanks Stephen. When I change my controller public ActionResult CAssigned(IEnumerable) it'll come Error 1 Identifier expected. What is that error? – Rob May 11 '15 at 02:27
  • You also need to give the parameter a name - `public ActionResult CAssigned(IList model)` - note I made it `IList` to match the model your passing to the view. Now `model` will contain the collection which you can loop through and save or whatever you want to do. –  May 11 '15 at 02:30
  • I am not quit sure how do I implement IList chtml page. Please give me example. – Rob May 11 '15 at 03:04
  • You need to edit your question to add the model and the GET method (and you should mark the existing method you have shown as `[HttpPost]` so its clear) –  May 11 '15 at 03:06
  • I have already update both my controller [HttpPost] and [HttpPost]. thank you – Rob May 11 '15 at 04:10

1 Answers1

1

Your use of a foreach loop does not generate the correct name attributes necessary to bind to a collection and you need to use a for loop or a custom EditorTemplate for typeof Location so that the form controls include an indexer. Refer this answer for more details on how form controls for a collection need to be named, and for using an EditorTemplate.

To use a for loop, you view needs to be

@model IList<yourAssembly.Location>
@using (Html.BeginForm()) // no need to add the parameters since you posting to the same method
{
  <table>
    for(int i = 0; i < Model.Count; i++)
    {
      <tr>
        <td>
          @Html.HiddenFor(m => m[i].LocationId)
          @Html.HiddenFor(m => m[i].MapIcons)
          @Html.DisplayFor(m => m[i].MapIcons)
        </td>
        <td>
          @Html.CheckBoxFor(m => m[i].Assigned)
        </td>
      </tr>
    }
  </table>
  <input type="Submit" value="Select" />
}

and you post method signature needs to be (add a name for the parameter)

[HttpPost] 
public ActionResult CAssigned(IEnumerable<Location> model)

Side notes:

  1. Remove the hidden input for the Assigned property. You have already generated a checkbox (and associated hidden input) for the property so it would just be ignore on postback anyway
  2. An <input> is not a valid child of a <tr> element, so make sure you include them inside a <td> element
Community
  • 1
  • 1
  • Thank for you code, I have one question [HttpPost] public ActionResult CAssigned(IEnumerable){ return View() }. Why was error come "Error 1 Identifier expected"? What do I have to change my controller? – Rob May 11 '15 at 05:03
  • I have update question with correct usage - like any method, you need to define the type and a name for the parameter - in you case you only included the type - `IEnumerable` - but omitted the name of the parameter –  May 11 '15 at 05:10
  • How about this controller [HttpPost] public ActionResult CAssigned(Location location) { return View(); { – Rob May 11 '15 at 05:37
  • See update. If it was `Location location` that means you method only accepts one `Location` object, but your view is creating and posting back multiple objects so it will not work. If you want to post back one `Location` then you your view needs to be designed to edit one object, not a collection. –  May 11 '15 at 05:42
  • Thank for your help Stephen, well done. It worked now this controller public ActionResult CAssigned(IEnumerable model) – Rob May 11 '15 at 05:56