asp.net-mvconclickeditorfor

Razor EditorFor with Onclick Event


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())

Solution

  • 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
    });