Jose M Martin
Jose M Martin

Reputation: 373

Checkbox adds extra "false" value per selected one

I have this piece of code in my View which belongs to a form

<div class="col-md-10">
@foreach (var l in leads)
{
    @: @Html.CheckBox("cbLead", false, new { @value = @l.Id }) @Html.TextBox("worth", "") - @Html.Label(l.Name)
}
</div>

And this is the form with I handle the post:

[HttpPost]
public ActionResult Update(string[] cbLead, double[] worth)
{
    // code
}

I have 24 checkboxes, but for each checkbox selected I receive 2 values in the Update method. So for example if I select 3 out of that 24 checkboxes, I receive 27 values in the string[] cblead.

Example with 24 checkboxes:

3 first checkboxes selected

And this is what I get in the method:

enter image description here

So I receive the value checked and an added false after. Any tips?

Upvotes: 1

Views: 119

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1039588

That's because the Html.CheckBox helper generates an additional hidden field with the same name and the value false. The reason for that is because if the checkbox is not checked, then no value will be sent to the server and thus the model binder will fail to properly bind to a boolean property on your model. Also notice that the Html.CheckBox helper expects that you are working with boolean values on your models. Your syntax here is incorrect:

@Html.CheckBox("cbLead", false, new { @value = @l.Id })

You seem to be trying to manually set the value attribute of the checkbox (which should not be done when using helpers) to the Id property of your model which I suppose is not boolean but rather a Guid as can be seen from the screenshot.

This is by design and is expected behavior. If you do not want this behavior that you could write your own custom helper or use plain HTML instead.

I suspect that what you need to receive on the server is the list of IDs along with a boolean value corresponding to whether the element was checked or not. For this purpose I suggest you writing the following view model:

public class MyViewModel
{
    public IList<LeadViewModel> Leads { get; set; }
}

public class LeadViewModel
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public string Worth { get; set; }
    public bool IsChecked { get; set; }
}

and then:

@for (var i = 0; i < Model.Leads.Count; i++)
{
    Html.CheckBoxFor(x => x.Leads[i].IsChecked)
    Html.HiddenFor(x => x.Leads[i].Id)
    Html.TextBoxFor(x => x.Leads[i].Worth) - 
    Html.LabelFor(x => x.Leads[i].Name)
}

Upvotes: 2

Related Questions