A disabled HTML element is not sent to the server when the form is submitted.
disabled - HTML: Hypertext Markup Language | MDN[
^]
To complicate things further, the
CheckBoxFor
and
CheckBox
helpers automatically render a hidden input with the same name, with the value set to
"false"
. This is to address the fact that an un-checked checkbox doesn't send anything to the server when it's submitted.
(The model binding code automatically removes this extra value if the checkbox is checked and enabled.)
AspNetWebStack/InputExtensions.cs at 749384689e027a2fcd29eb79a9137b94cea611a8 · aspnet/AspNetWebStack · GitHub[
^]
But you can use this extra hidden input to resolve the problem.
Start by simplifying your view:
<div class="col-md-6">
<span class="checkbox" style="margin-left: 26px;">
@Html.CheckBoxFor(m => m.IsPackage, new { @id = "package-checkbox" })
<span>@Model.GetDisplayName(m => m.IsPackage)</span>
</span>
</div>
<div class="col-md-6">
<span class="checkbox" style="margin-left: 26px;">
@Html.CheckBoxFor(m => m.IsDataPoint, new { @id = "datapoint-checkbox" })
<span>@Model.GetDisplayName(m => m.IsDataPoint)</span>
</span>
</div>
Then have your Javascript change the value of the hidden input to match the expected default value:
$(function(){
function togglePackage(){
var isPackage = $("#package-checkbox").is(":checked");
if (isPackage) {
$("#datapoint-checkbox").prop("checked", true).prop("disabled", true);
$("input[type='hidden'][name='IsDataPoint']").val("true");
}
else {
$("#datapoint-checkbox").prop("disabled", false);
$("input[type='hidden'][name='IsDataPoint']").val("false");
}
};
$(document).on('change', '#package-checkbox', togglePackage);
togglePackage();
});
I'd also recommend changing how you use your model so that this condition is enforced on the server as well as the client:
public class YourViewModel
{
public bool IsPackage { get; set; }
public bool IsDataPoint { get; set; }
internal bool IsReallyDataPoint => IsPackage || IsDataPoint;
}
Anywhere in your server-side code where you want to check whether the model is a data-point, use the
IsReallyDataPoint
property instead.