Checkbox for nullable boolean

My model has a boolean which should be NULL

public bool? Foo { get; set; } 

so in my razor cshtml i have

 @Html.CheckBoxFor(m => m.Foo) 

except that does not work. Also does not throw it (bool). If i do

 @Html.CheckBoxFor(m => m.Foo.Value) 

which does not create an error, but does not bind to my model when publishing, and foo is null. What is the best way to display Foo on a page and bind it to my model in a post?

+91
nullable asp.net-mvc-3 razor
Jul 27 '11 at 19:02
source share
17 answers

I got it to work with

 @Html.EditorFor(model => model.Foo) 

and then creating Boolean.cshtml in my EditorTemplates folder and sticking

 @model bool? @Html.CheckBox("", Model.GetValueOrDefault()) 

inside.

+100
Jul 28 '11 at 3:11
source share

An answer was found in a similar question - Rendering a Nullable Bool as a CheckBox . It is very simple and just works:

 @Html.CheckBox("RFP.DatesFlexible", Model.RFP.DatesFlexible ?? false) @Html.Label("RFP.DatesFlexible", "My Dates are Flexible") 

This is like the accepted answer from @afinkelstein, except that we donโ€™t need a special editor template

+39
Jun 01 '15 at 9:07
source share

Do I have a bool? IsDisabled { get; set; } bool? IsDisabled { get; set; } bool? IsDisabled { get; set; } in the model. Inserted if in a view.

 <div class="inputClass" id="disabled"> <div> @if(Model.IsDisabled==null) { Model.IsDisabled = false; } @Html.CheckBoxFor(model => model.IsDisabled.Value) </div> </div> 
+25
Jun 20 2018-12-12T00:
source share

My model has a boolean which should be NULL

Why? It does not make sense. The flag has two states: checked / not set, or True / False, if you want. There is no third state.

Or wait while you use your domain models in your views instead of viewing models? It's your problem. Therefore, the solution for me is to use a view model in which you define a simple logical property:

 public class MyViewModel { public bool Foo { get; set; } } 

and now you will have the action of your controller to pass this view model to the view and create the corresponding flag.

+14
Jul 27 '11 at 19:13
source share

Simplify the primitive with hidden fields to find out if False or Null is not recommended.

The checkbox is not what you should use - it really has only one state: Checked . Otherwise, it could be anything.

When the database field is null logical ( bool? ), UX should use 3-radio buttons, where the first button represents your โ€œVerifiedโ€, the second button represents โ€œNot Verifiedโ€, and the third button represents your null, regardless of the semantics of the null value. You can use the <select><option> drop-down list to save the property, but the user must double-click, and the selection is not as fast as instant.

  1 0 null True False Not Set Yes No Undecided Male Female Unknown On Off Not Detected 

A RadioButtonList, defined as an extension named RadioButtonForSelectList, creates switches for you, including the selected / checked value, and sets <div class="RBxxxx"> so that you can use css so that your switches switch horizontally (display: inline block), vertical or tabular (display: built-in unit, width: 100 pixels;)

In the model (I use a string, a string to define a dictionary as a pedagogical example. You can use bool ?, string)

 public IEnumerable<SelectListItem> Sexsli { get; set; } SexDict = new Dictionary<string, string>() { { "M", "Male"}, { "F", "Female" }, { "U", "Undecided" }, }; //Convert the Dictionary Type into a SelectListItem Type Sexsli = SexDict.Select(k => new SelectListItem { Selected = (k.Key == "U"), Text = k.Value, Value = k.Key.ToString() }); <fieldset id="Gender"> <legend id="GenderLegend" title="Gender - Sex">I am a</legend> @Html.RadioButtonForSelectList(m => m.Sexsli, Model.Sexsli, "Sex") @Html.ValidationMessageFor(m => m.Sexsli) </fieldset> public static class HtmlExtensions { public static MvcHtmlString RadioButtonForSelectList<TModel, TProperty>( this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> listOfValues, String rbClassName = "Horizontal") { var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); var sb = new StringBuilder(); if (listOfValues != null) { // Create a radio button for each item in the list foreach (SelectListItem item in listOfValues) { // Generate an id to be given to the radio button field var id = string.Format("{0}_{1}", metaData.PropertyName, item.Value); // Create and populate a radio button using the existing html helpers var label = htmlHelper.Label(id, HttpUtility.HtmlEncode(item.Text)); var radio = String.Empty; if (item.Selected == true) { radio = htmlHelper.RadioButtonFor(expression, item.Value, new { id = id, @checked = "checked" }).ToHtmlString(); } else { radio = htmlHelper.RadioButtonFor(expression, item.Value, new { id = id }).ToHtmlString(); }// Create the html string to return to client browser // eg <input data-val="true" data-val-required="You must select an option" id="RB_1" name="RB" type="radio" value="1" /><label for="RB_1">Choice 1</label> sb.AppendFormat("<div class=\"RB{2}\">{0}{1}</div>", radio, label, rbClassName); } } return MvcHtmlString.Create(sb.ToString()); } } 
+7
May 2, '12 at 15:19
source share

The flag contains only 2 values โ€‹โ€‹(true, false). Nullable boolean has 3 values โ€‹โ€‹(true, false, null), so this cannot be done using the checkbox.

A good option is to use a drop down list.

Model

 public bool? myValue; public List<SelectListItem> valueList; 

controller

 model.valueList = new List<SelectListItem>(); model.valueList.Add(new SelectListItem() { Text = "", Value = "" }); model.valueList.Add(new SelectListItem() { Text = "Yes", Value = "true" }); model.valueList.Add(new SelectListItem() { Text = "No", Value = "false" }); 

View

 @Html.DropDownListFor(m => m.myValue, valueList) 
+4
Feb 10 '14 at 2:05
source share

For me, the solution was to change the presentation model. Think you are looking for an invoice. These invoices can be paid or not. So your search has three options: Paid, Unpaid, or I Don't Care.

I had it originally as a bool? field:

 public bool? PaidInvoices { get; set; } 

It made me stumble upon this question. I ended up creating an Enum type, and I processed it as follows:

 @Html.RadioButtonFor(m => m.PaidInvoices, PaidStatus.NotSpecified, new { @checked = true }) @Html.RadioButtonFor(m => m.PaidInvoices, PaidStatus.Yes) @Html.RadioButtonFor(m => m.PaidInvoices, PaidStatus.No) 

Of course, I wrapped them in labels and indicated the text, I just mean here another option for consideration.

+3
Nov 08 '13 at 16:32
source share

I would create a template for it and use this template with EditorFor ().

Here is how I did it:

  • Create your template, which is basically a partial view that I created in the EditorTemplates directory, in the "General" section of the "Views" section it is like (for example): CheckboxTemplate :

     @using System.Globalization @using System.Web.Mvc.Html @model bool? @{ bool? myModel = false; if (Model.HasValue) { myModel = Model.Value; } } <input type="checkbox" checked="@(myModel)" name="@ViewData.TemplateInfo.HtmlFieldPrefix" value="True" style="width:20px;" /> 
  • Use it like this (in any view):

    @ Html.EditorFor (x => x.MyNullableBooleanCheckboxToBe, "CheckboxTemplate")

That's all.

Templates are so powerful in MVC that they are used. You can create an entire page as a template that you would use with @Html.EditorFor() ; provided that you pass your view model in a lambda expression.

+3
Jun 09 '15 at 16:12
source share

The cleanest approach I could offer is to extend the extensions available to HtmlHelper while reusing the functionality provided by the framework.

 public static MvcHtmlString CheckBoxFor<T>(this HtmlHelper<T> htmlHelper, Expression<Func<T, bool?>> expression, IDictionary<string, object> htmlAttributes) { ModelMetadata modelMeta = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); bool? value = (modelMeta.Model as bool?); string name = ExpressionHelper.GetExpressionText(expression); return htmlHelper.CheckBox(name, value ?? false, htmlAttributes); } 

I experimented with the "formation" of the expression to allow a direct pass to the native CheckBoxFor<Expression<Func<T, bool>>> , but I do not think it is possible.

+3
Jun 09 '16 at 8:58
source share

I had a similar problem in the past.

Create a checkbox in the HTML block and set the attribute name = "Foo". This must be correctly published.

 <input type="checkbox" name="Foo" checked="@model.Foo.Value" /> Foo Checkbox<br /> 
+1
Jul 27 '11 at 7:11
source share

Just check the null value and return it false:

 @{ bool nullableValue = ((Model.nullableValue == null) || (Model.nullableValue == false)) ? false : true; } @Html.CheckBoxFor(model => nullableValue) 
0
Nov 10 '14 at 15:16
source share

I also ran into the same problem. I tried the following approach to solve the problem because I do not want to change the database and generate EDMX again.

 @{ bool testVar = (Model.MYVar ? true : false); } <label>@Html.CheckBoxFor(m => testVar)testVar</label><br /> 
0
Dec 22 '14 at 8:46
source share

When creating an EditorTemplate for a model containing a nullable bool ...

  • Divide the nullable bool into 2 booleans:

     // Foo is still a nullable boolean. public bool? Foo { get { if (FooIsNull) return null; return FooCheckbox; } set { FooIsNull = (value == null); FooCheckbox = (value ?? false); } } // These contain the value of Foo. Public only so they are visible in Razor views. public bool FooIsNull { get; set; } public bool FooCheckbox { get; set; } 
  • In the editor template:

     @Html.HiddenFor(m => m.FooIsNull) @if (Model.FooIsNull) { // Null means "checkbox is hidden" @Html.HiddenFor(m => m.FooCheckbox) } else { @Html.CheckBoxFor(m => m.FooCheckbox) } 
  • Do not return the original Foo property, because it is now calculated from FooIsNull and FooCheckbox.

0
Feb 11 '16 at 17:34
source share

All of the above answers brought their problems. The easiest / cleanest IMO way is to create an assistant

MVC5 Razor

App_Code / Helpers.cshtml

 @helper CheckBoxFor(WebViewPage page, string propertyName, bool? value, string htmlAttributes = null) { if (value == null) { <div class="checkbox-nullable"> <input type="checkbox" @page.Html.Raw(htmlAttributes)> </div> } else if (value == true) { <input type="checkbox" value="true" @page.Html.Raw(htmlAttributes) checked> } else { <input type="checkbox" value="false" @page.Html.Raw(htmlAttributes)> } } 

Using

 @Helpers.CheckBoxFor(this, "IsPaymentRecordOk", Model.IsPaymentRecordOk) 

In my scenario, a checkbox with a null value means that the employee has not yet asked the client a question, so he is enclosed in .checkbox-nullable so that you can customize the style accordingly and help the end user determine that he is not true and false

CSS

 .checkbox-nullable { border: 1px solid red; padding: 3px; display: inline-block; } 
0
Jul 01 '16 at 4:50
source share

Extension Methods:

  public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool?>> expression) { return htmlHelper.CheckBoxFor<TModel>(expression, null); } public static MvcHtmlString CheckBoxFor<TModel>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, bool?>> expression, object htmlAttributes) { ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); bool? isChecked = null; if (metadata.Model != null) { bool modelChecked; if (Boolean.TryParse(metadata.Model.ToString(), out modelChecked)) { isChecked = modelChecked; } } return htmlHelper.CheckBox(ExpressionHelper.GetExpressionText(expression), isChecked??false , htmlAttributes); } 
0
Aug 09 '17 at 11:00
source share
 @{ bool testVar = ((bool)item.testVar ? true : false); } @Html.DisplayFor(modelItem => testVar) 
-one
Aug 13 '15 at 17:32
source share

This is an old question, and existing answers describe most alternatives. But is there one simple option if you have a bool? in your view model, and you don't care about zero in the user interface:

 @Html.CheckBoxFor(m => m.boolValue ?? false); 
-3
Mar 27 '14 at 14:52
source share



All Articles