Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rendering Nullable Bool as CheckBox

I'm new from WebForms to MVC. I have view model field with the type bool? and, by default, EditorFor() renders this field as a DropDownList with a "Not Set" option. I would prefer to render it as a CheckBox and, if the value is null, just set it to unchecked.

The field name is RFP.DatesFlexible and so I wrote the following markup in my view:

<input type="checkbox" id="RFP_DatesFlexible" name="RFP.DatesFlexible" />
<label for="RFP_DatesFlexible">My Dates are Flexible</label>

But this doesn't work. The result is always null and ModelState.IsValid is false.

Can anyone say how I could make this work?

EDIT

This is the code I ended up with, which appears to work fine.

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

The label is correctly associated with the checkbox so that clicking the text will toggle the checkbox.

like image 344
Jonathan Wood Avatar asked Dec 13 '11 03:12

Jonathan Wood


People also ask

Can bool be nullable?

Nullable boolean can be null, or having a value “true” or “false”. Before accessing the value, we should verify if the variable is null or not.

How do you check if a boolean is nullable?

Turns out, you can just do this instead: bool? nullableBool = true; if (nullableBool == true) { // some code... } nullableBool == true will evaluate to false if nullableBool is either false or null , in other words: not true.


2 Answers

Something like this?

Models:

public class MyViewModel
{
    public ViewModel2 RDP { get; set; }
}

public class ViewModel2
{
    public bool? DatesFlexible { get; set; }
}

Controller:

    public ActionResult TestBool()
    {
        return View(new MyViewModel { RDP = new ViewModel2() });
    }

    [HttpPost]
    public ActionResult TestBool(MyViewModel vm)
    {
        return View();
    }

View:

@model mvc_testing_2.Models.MyViewModel

@using (Html.BeginForm())
{
    @Html.CheckBox("RDP.DatesFlexible", 
        Model.RDP.DatesFlexible != null && (bool)Model.RDP.DatesFlexible)

    <input type="submit" value="go" />
}
like image 147
hawkke Avatar answered Oct 12 '22 17:10

hawkke


First, I think it would help to understand how Html.CheckBox works. It's not quite what you'd expect. Take a look at HTML.CheckBox Behaviour

To answer your question, the reason your code doesn't work is because your <input /> requires a value='true' to bind correctly. For example:

<input type='checkbox' name='RFP.DatesFlexible' value='true' />

And add a checked='checked' property if it should be checked.

That's why I usually override the Html.CheckBoxmethod with my own. The default implementation is just confusing.

like image 37
Scott Rippey Avatar answered Oct 12 '22 18:10

Scott Rippey