0

I am trying to get the selected checkboxes value

this are my models,

public class VehicleViewModel : Vehicle
{
    [Display(Name = "Vehicle Type")]
    [Required( ErrorMessage = "{0} is required.")]
    public string VehicleTypeName { get; set; }

    [Display(Name = "Location")]
    [Required(ErrorMessage = "{0} is required.")]
    public string LocationName { get; set; }

    public IEnumerable<AssignProductsViewModel> AssignedProducts { get; set; }
}

public class AssignProductsViewModel
{
    public long ProductID { get; set; }
    public string ProductName { get; set; }
}

here's my razor view

@foreach (var item in Model.AssignedProducts)
{
  <tr>
    <td>
      <input type="checkbox" value ="@item.ProductID"/>
    </td>
    <td>
      @Html.DisplayFor(model => item.ProductName)
    </td>
  </tr>
}

and here's my controller

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult NewVehicle(VehicleViewModel vehicleViewModel, string selected)
{
  //Do something with the string here
  return View();
}

I know I need to pass the selected check boxes value to a string using javascript and pass the string to a controller. But i have no idea how to do it since I'm a newbie in javascript and MVC.

lynncasiano
  • 861
  • 1
  • 10
  • 10
  • Your checkboxes don't even have a `name` attribute so wont post back. You also creating invalid html with duplicate `id` attributes. Then you would need to make the parameter an array e.g. `string[] selectedCheckboxes` although property `ProductID` suggests its probably `int` anyway. Start by looking at the [jquery ajax documentation](http://api.jquery.com/jquery.ajax/) to understand how to post using ajax. –  Feb 11 '15 at 03:08
  • You always use the FormCollection. http://stackoverflow.com/questions/21303236/mvc-razor-get-option-value-from-select-with-formcollection – Tim Southard Feb 11 '15 at 03:52
  • @TimSouthard , is it applicaple with tables? and i need to be able to check mulitiple checkboxes as posibble. Thanks. :) – lynncasiano Feb 11 '15 at 04:26
  • It'll work with any tags as long as you use a form. – Tim Southard Feb 11 '15 at 04:30
  • Do not use `FormCollection`. You should always bind to a model and let MVC take care of binding and validation for you. And is there a reason you need to use ajax to post rather than a standard form submit? –  Feb 11 '15 at 04:58
  • @StephenMuecke, i thought of using ajax because i am not sure how to bind my model, but it would be a lot better if there is a way that i will not be using ajax, thanks – lynncasiano Feb 11 '15 at 05:44
  • You simply need to use a view model that represents what you want to display/edit. In your case a `boolen` property (say) `IsSelected` that you can bind a checkbox to, and post back the collection.I'll add answer shortly –  Feb 11 '15 at 05:47

1 Answers1

1

Based on the comments that an ajax post is not required, your AssignProductsViewModel requires an additional property to bind the checkboxes

public class AssignProductsViewModel
{
  public long ProductID { get; set; }
  public string ProductName { get; set; }
  public bool IsSelected { get; set; } // add this
}

In the view, use a for loop or a custom EditorTemplate to render the collection do the controls are correctly named with indexers. A foreach loop generates duplicate id (invalid html) and name attributes (cannot be bound to a collection)

@model VehicleViewModel
@using(Html.BeginForm())
{
  // controls for VehicleTypeName, LocationName
  for(int i = 0; i < Model.AssignedProducts.Count; i++)
  {
    @Html.HiddenFor(m => m.AssignedProducts[i].ProductID) // ditto for ProductName if you want it on postback
    @Html.CheckBoxFor(m => m.AssignedProducts[i].IsSelected)
    @Html.LabelFor(m => m.AssignedProducts[i].IsSelected, Model.AssignedProducts[i].ProductName)
  }
  ....
}

and post back to

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult NewVehicle(VehicleViewModel model)
{
  // model.AssignedProducts contains the collection with a value indicating if the product has been selected
}

Alternatively, you can use an EditorTemplate for type of AssignProductsViewModel to render the collection

In /Views/Shared/EditorTemplates/AssignProductsViewModel.cshtml

@model AssignProductsViewModel
@Html.HiddenFor(m => m.ProductID) // ditto for ProductName if you want it on postback
@Html.CheckBoxFor(m => m.IsSelected)
@Html.LabelFor(m => m..IsSelected, Model.ProductName)

and in the main view

@model VehicleViewModel
@using(Html.BeginForm())
{
  // controls for VehicleTypeName, LocationName
  @Html.EditorFor(m => m.AssignedProducts)
  <input type="submit" />
}    
  • i tried your code but i am having an error on for loop : CS0019: Operator '<' cannot be applied to operands of type 'int' and 'method group' – lynncasiano Feb 11 '15 at 06:34
  • Oops, didn't notice your property was `IEnumerable`. It needs to be `IList`. But if you can;t change it, then you can use a custom `EditorTemplate` (I'll update answer to add that option anyway) –  Feb 11 '15 at 06:36