0

I have searched some articles but none of them fits with my problem. i have this code in my cshtml

@model IEnumerable<MonitoreoIntegrado.Models.Sensores>
@using (Html.BeginForm("Graphics", "Datos_extensometro", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    <div style="margin:0; padding:0; border:none; position:absolute; bottom:5px; right:25px;"><input type="submit" id="enviar" class="btn btn-primary" value="Consultar"></div>
    <div style="float:left; width:428px; height:105px; padding:5px; overflow-y: scroll;">
        <h4 style="margin-top:0px;">Consultar multiples sensores</h4>
            @foreach (var item in Model)
            {
                @Html.CheckBox("sensoresCB", false, new { value = @item.idSensor.ToString() }) @item.nombre <a class="moverse" objetivo="@(item.idSensor)" href=""><span class="glyphicon glyphicon-map-marker" title="Ir al marcador"></span></a><br />
            }
    </div>
}

and this in my controller:

[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = RolesSistema.Administrador + "," + RolesSistema.Lectura)]
public ActionResult Graphics()
{
    return View();
}

I need help to receive that checkboxes in my controller and check which of them are checked

Clamari
  • 353
  • 4
  • 17

4 Answers4

1

You should use unique id's for your inputs. The easiest way:

@for (var i = 0; i < Model.Count(); i++)
{
    @Html.CheckBox("sensoresCB["+i.ToString()+"]", false, new { value = Model[i].idSensor.ToString() })
    //your other stuff
}

And on controller side:

[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = RolesSistema.Administrador + "," + RolesSistema.Lectura)]
public ActionResult Graphics(bool[] sensoresCB) //note this
{
    return View();
}

So you got the array with your selections. Use index to understand what checkbox it is.

teo van kot
  • 12,350
  • 10
  • 38
  • 70
1

You could extend the model of item with a Checked property or similar.

public class GraphicsViewModel {
   public GraphicsItemViewModel[] Items { get; set; }
}

public class GraphicsItemViewModel {
   public bool Checked { get; set; }
   public long IdSensor { get; set; }
}

Then you can render the checkbox with a binding to this Checked property.

@model GraphicsViewModel 
@using (Html.BeginForm(/* ....*/) {
    // use a for loop so the array is bound correctly
    @for (int i = 0; i < Model.Items.Length; i++) { 
       @Html.CheckBoxFor(m => m.Items[i].Checked)
       // post back IdSensor value so we can access it in the controller
       @Html.HiddenFor(m => m.Items[i].IdSensor) 
    }
}

Your controller should accept a model for the POST data, you can reuse the ViewModel:

[HttpPost]
public ActionResult Graphics(GraphicsViewModel postData) {
  bool areAllChecked = postData.Items.All(i => i.Checked);
  bool isFirstChecked = postData.Items.First().Checked;
  bool isCertainIdChecked = postData.Items.Single(i => i.IdSensor == 1337).Checked;
  // ...
}
Georg Patscheider
  • 9,357
  • 1
  • 26
  • 36
  • my model in this view is very big. It has a lot of properties and subclases in use. making an extended class would make me write a huge constructor for that class. the current model used is taken directly from the database model. is there any way to just set property checked as false in the view checkbox i always need the checkboxes clear? – Clamari Jun 09 '17 at 14:02
  • Well the problem is that you need some property to bind the user selected values back so you can work with them in the controller. You could compose a new ViewModel that consists of the database model and the additional properties (without using inheritance). – Georg Patscheider Jun 12 '17 at 07:14
  • still i can't solve this. my model is `@model IEnumerable` as you can see it is a IEnumerable. so every `Sensores` object should have it's own `Checked` property. and not a list items for each one and I think my controller should receive something like `IEnumerable sensores` as parameter, however, it's not working. i don't know what am i doing bad. I need more help please. – Clamari Jun 12 '17 at 18:31
  • Using `IEnumerable` as model and having a `Checked` property for every sensor sounds reasonable. There are some pitfalls when model binding collections, see [Model Binding to a List MVC 4](https://stackoverflow.com/questions/15375800/model-binding-to-a-list-mvc-4). Basically, you must make sure the rendered `` elements have the correct names (which include an index). – Georg Patscheider Jun 13 '17 at 06:54
0

I would like to mention a helpful point here, that is

If a checkbox is checked, then the postback values will contain a key-value pair of the form [InputName]=[InputValue]

If a checkbox is not checked, then the posted form contains no reference to the checkbox at all.

So in a controller action method, you can use the name of the checkbox and get the values which is only checked

ex:

public ActionResult Graphics(bool[] sensoresCB) 
{
    return View();
}

Hope above information was helpful

Thanks

Karthik

Karthik Elumalai
  • 1,574
  • 1
  • 11
  • 12
0

Based on @teo van kot reply I achieved to recover the checkboxes values. This is my working code.

Controller:

[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = RolesSistema.Administrador + "," + RolesSistema.Lectura)]
public ActionResult Graphics(int[] sensoresCB)//you can receive a string[] as well
{
    //code and stuff
    return View();
}

View:

@model IEnumerable<MonitoreoIntegrado.Models.Sensores>
@using (Html.BeginForm("Graphics", "Datos_extensometro", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    //some code stuff
    @{
        int i = 0;
        foreach (var item in Model)
        {
            @Html.CheckBox("sensoresCB[" + i.ToString() + "]", false, new { value = item.idSensor.ToString() }) @item.nombre<br />
            i++;
        }
    }
}
Clamari
  • 353
  • 4
  • 17