82

All I want to know is the proper syntax for the Html.CheckBoxFor HTML helper in ASP.NET MVC.

What I'm trying to accomplish is for the check-box to be initially checked with an ID value so I can reference it in the Controller to see if it's still checked or not.

Would below be the proper syntax?

@foreach (var item in Model.Templates) 
{ 
    <td> 
        @Html.CheckBoxFor(model => true, item.TemplateId) 
        @Html.LabelFor(model => item.TemplateName)
    </td> 
}
SteveC
  • 15,808
  • 23
  • 102
  • 173
sagesky36
  • 4,542
  • 19
  • 82
  • 130
  • is `item` part of your model or what? – Robert Koritnik Oct 01 '12 at 13:53
  • No... Here is the full code in the HTML @foreach (var item in Model.Templates) { @Html.CheckBoxFor(model => true, item.TemplateId) @Html.LabelFor(model => item.TemplateName) } – sagesky36 Oct 01 '12 at 13:58
  • The purpose of the `CheckBoxFor()` (and `CheckBox()`) method is to bind to a `bool` property. Since `TemplateId` does not appear to be `bool`, then do not use `CheckBoxFor()` - just generate the html manually, or to do it the mvc way - refer [this answer](https://stackoverflow.com/questions/29542107/pass-list-of-checkboxes-into-view-and-pull-out-ienumerable/29554416#29554416) –  May 18 '18 at 00:25

7 Answers7

130

That isn't the proper syntax

The first parameter is not checkbox value but rather view model binding for the checkbox hence:

@Html.CheckBoxFor(m => m.SomeBooleanProperty, new { @checked = "checked" });

The first parameter must identify a boolean property within your model (it's an Expression not an anonymous method returning a value) and second property defines any additional HTML element attributes. I'm not 100% sure that the above attribute will initially check your checkbox, but you can try. But beware. Even though it may work you may have issues later on, when loading a valid model data and that particular property is set to false.

The correct way

Although my proper suggestion would be to provide initialized model to your view with that particular boolean property initialized to true.

Property types

As per Asp.net MVC HtmlHelper extension methods and inner working, checkboxes need to bind to boolean values and not integers what seems that you'd like to do. In that case a hidden field could store the id.

Other helpers

There are of course other helper methods that you can use to get greater flexibility about checkbox values and behaviour:

@Html.CheckBox("templateId", new { value = item.TemplateID, @checked = true });

Note: checked is an HTML element boolean property and not a value attribute which means that you can assign any value to it. The correct HTML syntax doesn't include any assignments, but there's no way of providing an anonymous C# object with undefined property that would render as an HTML element property.

Robert Koritnik
  • 103,639
  • 52
  • 277
  • 404
  • 2
    Thanks a lot for explaining it to me.... Seems that this html helper really gave me a headache. I took your advice and initialized the isChecked property to TRUE. – sagesky36 Oct 01 '12 at 14:18
  • Nice HOWTO on CheckBox() and CheckBoxFor(): http://www.tutorialsteacher.com/mvc/htmlhelper-checkbox-checkboxfor – Wouter May 15 '18 at 08:16
  • There is a catch. Make sure the field in the database is not nullable or you'll have problems – John Swaringen Sep 13 '18 at 19:36
17

By default, the below code will NOT generate a checked Check Box as model properties override the html attributes:

@Html.CheckBoxFor(m => m.SomeBooleanProperty, new { @checked = "checked" });

Instead, in your GET Action method, the following needs to be done:

model.SomeBooleanProperty = true;

The above will preserve your selection(If you uncheck the box) even if model is not valid(i.e. some error occurs on posting the form).

However, the following code will certainly generate a checked checkbox, but will not preserve your uncheck responses, instead make the checkbox checked every time on errors in form.

 @Html.CheckBox("SomeBooleanProperty", new { @checked = "checked" });

UPDATE

//Get Method
   public ActionResult CreateUser(int id)
   {
        model.SomeBooleanProperty = true;         
   }

Above code would generate a checked check Box at starting and will also preserve your selection even on errors in form.

T Gupta
  • 947
  • 11
  • 11
  • Thanks! You saved me! I kept getting a null reference on my bool because I was failing to initialize it in my GET. – Flea Feb 22 '14 at 14:43
  • This looked like it was going to save me, but I can't put the pieces together. When my page loads, it shows the checkboxes appropriately. When the page has a server-side invalid model on post-back, the resulting page does not show the checkboxes checked even though the model has the values as true. I'm not sure what you mean by "GET Action" except maybe to set it to true in my controller, but I have already set it to true there. Any idea what I am missing? – Kirk Liemohn Jul 01 '14 at 16:37
  • I posted an answer that worked for me. Not ideal, but I got it to work. – Kirk Liemohn Jul 01 '14 at 17:18
9

Place this on your model:

[DisplayName("Electric Fan")]
public bool ElectricFan { get; set; }

private string electricFanRate;

public string ElectricFanRate
{
    get { return electricFanRate ?? (electricFanRate = "$15/month"); }
    set { electricFanRate = value; }
}

And this in your cshtml:

<div class="row">
    @Html.CheckBoxFor(m => m.ElectricFan, new { @class = "" })
    @Html.LabelFor(m => m.ElectricFan, new { @class = "" })
    @Html.DisplayTextFor(m => m.ElectricFanRate)
</div>

Which will output this:

MVC Output If you click on the checkbox or the bold label it will check/uncheck the checkbox

James Gray
  • 334
  • 3
  • 9
8

I was having a problem with ASP.NET MVC 5 where CheckBoxFor would not check my checkboxes on server-side validation failure even though my model clearly had the value set to true. My Razor markup/code looked like:

@Html.CheckBoxFor(model => model.MyBoolValue, new { @class = "mySpecialClass" } )

To get this to work, I had to change this to:

@{
    var checkboxAttributes = Model.MyBoolValue ?
        (object) new { @class = "mySpecialClass", @checked = "checked" } :
        (object) new { @class = "mySpecialClass" };
}
@Html.CheckBox("MyBoolValue", checkboxAttributes)
Kirk Liemohn
  • 7,733
  • 9
  • 46
  • 57
  • 1
    I had the same problem, in my case I can use ModelState.Clear. Is this because it is using your postback value rather than whatever you set in the controller? http://weblog.west-wind.com/posts/2012/Apr/20/ASPNET-MVC-Postbacks-and-HtmlHelper-Controls-ignoring-Model-Changes – tony Jan 06 '15 at 07:36
4

None of the above answers worked for me when binding back on POST, until I added the following in CSHTML

<div class="checkbox c-checkbox">
    <label>
        <input type="checkbox" id="xPrinting" name="xPrinting" value="true"  @Html.Raw( Model.xPrinting ? "checked" : "")>
        <span class=""></span>Printing
    </label>
</div>


// POST: Index

[HttpPost]
public ActionResult Index([Bind(Include = "dateInHands,dateFrom,dateTo,pgStatus,gpStatus,vwStatus,freeSearch,xPrinting,xEmbroidery,xPersonalization,sortOrder,radioOperator")] ProductionDashboardViewModel model)
bummi
  • 27,123
  • 14
  • 62
  • 101
Craig Trombly
  • 464
  • 2
  • 9
1

I was looking for the solution to show the label dynamically from database like this:

checkbox1 : Option 1 text from database
checkbox2 : Option 2 text from database
checkbox3 : Option 3 text from database
checkbox4 : Option 4 text from database

So none of the above solution worked for me so I used like this:

 @Html.CheckBoxFor(m => m.Option1, new { @class = "options" }) 
 <label for="Option1">@Model.Option1Text</label>

 @Html.CheckBoxFor(m => m.Option2, new { @class = "options" }) 
 <label for="Option2">@Mode2.Option1Text</label>

In this way when user will click on label, checkbox will be selected.

Might be it can help someone.

Ali Adravi
  • 21,707
  • 9
  • 87
  • 85
1

I had trouble getting this to work and added another solution for anyone wanting/ needing to use FromCollection.

Instead of:

@Html.CheckBoxFor(model => true, item.TemplateId) 

Format html helper like so:

@Html.CheckBoxFor(model => model.SomeProperty, new { @class = "form-control", Name = "SomeProperty"})

Then in the viewmodel/model wherever your logic is:

public void Save(FormCollection frm)
{   
    // to do instantiate object.

    instantiatedItem.SomeProperty = (frm["SomeProperty"] ?? "").Equals("true", StringComparison.CurrentCultureIgnoreCase);

    // to do and save changes in database.
}