0

I have nullable Boolean value that is being presented as a checkbox using the following code:

@Html.EditorFor(m => m.IsInitialStatus, new { htmlAttributes = new { @onclick = "InitialOrStarting()" } })

however the @onclick attribute is not being added to the HTML when the page is loaded. Am I missing something here? I had taken the example from an answer on this page.

I have also looked at changing this to a CheckBoxFor but keep getting an issue with the nullable Bool datatypes.

Any help on this would be appreciated! I just want a nullable bool checkbox with an onClick event firing to a Javascript function... I am not the most advanced user but this seems to be more difficult for me to do than maybe it should!?

EDIT

There appears to be an EditorTemplate for Boolean which contains:

@model bool?

@Html.CheckBox("", Model.GetValueOrDefault())
CJH
  • 1,266
  • 2
  • 27
  • 61
  • A nullable bool will be generated as a dropdownlist (with 3 values for Not Set, True and False, not a checkbox, so what you are claiming is not possible unless you have created a specific `EditorTemplate` for `bool?` - in which case show it) –  May 08 '18 at 11:54
  • And if you have created a custom `EditorTemplate`, then generating a checkbox makes no sense for a `bool?` –  May 08 '18 at 11:55
  • Thanks for the reply... I was just reading about EditorTemplates just now. This is code I have inherited so am going to check for one now. – CJH May 08 '18 at 12:08
  • Start by looking in the `/Views/Shared/EditorTemplates` folder for a `bool.cshtml` file –  May 08 '18 at 12:13
  • I have just updated the call with details of an EditorTemplate. I have however started to go down the route of ensuring there is no Null passed to a CheckBoxFor as it seems more straight forward at this stage. – CJH May 08 '18 at 12:22
  • I strongly suggest you delete that template - it makes no sense - a `bool?` has 3 states, but a checkbox has only 2 states. But the reason that you get no attributes, is that you are not reading the values from the `ViewDataDictionary` and adding it in the `CheckBox()` method –  May 08 '18 at 12:26
  • Thanks again Stephen... I have escalated the issue with the three state Boolean. I have personally always been of the school that a bool is two a choice of two. I am intrigued by what you mentioned there about the ViewDataDictionary... How do I go about that? Are you able to supply an example please? – CJH May 08 '18 at 13:08
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/170618/discussion-between-stephen-muecke-and-cjh). –  May 08 '18 at 13:08

2 Answers2

1

You are using the overload of EditorFor() where the 2nd parameter is additionalViewData. If you did not have a specific EditorTemplate for bool?, the method would generate the default template, which is a <select> with 3 values for null, true and false, and include the attributes.

But because you have an EditorTemplate, you need to add the attributes yourself by reading the value from the ViewDataDictionary (typically, an EditorTemplate includes multiple html elements, so the method cannot know which element you want to apply the attributes to).

Your template would need to be

@model bool?
@{ var attributes = ViewData["htmlAttributes"]; }
@Html.CheckBox("", Model.GetValueOrDefault(), attributes)

Having said that, your should not be doing this. A bool? has 3 states (null, true or false) but a checkbox has only 2 states - on or off (translates to true or false) so your EditorTemplate does not represent the possible values of your property.

If you only want to allow true or false, then your property should not be nullable. Alternatively, use the default template that does allow a null selection (or if you want an alternative UI, create a template that renders 3 radio buttons for example)

In addition, I recommend you stop polluting you markup with behavior and use Unobtrusive JavaScript - i.e. your script will be

$(yourCheckBox).click(function() {
    ... // do something
});
0

Onclick Event does not working for @HtmlEditorFor. But you can use class attribute.

<script>
    $(".single-checkbox").on("change", function () {
        if ($(".single-checkbox:checked").length > 2) {
            this.checked = false;
            alert ("Only 2 choice")
        }
    });
</script>
@Html.EditorFor(model => model.YourProperty, new { htmlAttributes = new { @class = "single-checkbox" } }) 
@Html.EditorFor(model => model.YourProperty, new { htmlAttributes = new { @class = "single-checkbox" } }) 
@Html.EditorFor(model => model.YourProperty, new { htmlAttributes = new { @class = "single-checkbox" } }) 
@Html.EditorFor(model => model.YourProperty, new { htmlAttributes = new { @class = "single-checkbox" } })