Click here to Skip to main content
15,887,596 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more: , +
Hi,

I have two Html.CheckBoxFor with names IsPackage and IsDataPoint.

When IsPackage is checked then IsDataPoint can also be checked and available for user to select the value.

When IsPackage is unchecked, IsDataPoint should also be checked and disabled. Here what the issue comes as when IsDataPoint is disabled it always gives FALSE value to controlled on posting the form.

I tried with adding the hidden field for IsDataPoint but it still does not retain the state of value.

What I have tried:

HTML
<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.HiddenFor(m=>m.IsDatapointFlagging, 
                        new { @id = "datapoint-flagging-hidden" })
        @Html.CheckBoxFor(m => m.IsDatapointFlagging, (Model.IsPackage ? 
            new { @id = "datapoint-flagging-checkbox" } 
            : (object)new { @id = "datapoint-flagging-checkbox", @disabled = "" }))
        <span>@Model.GetDisplayName(m => m.IsDatapointFlagging)</span>
    </span>
</div>


I also tried setting the hidden field value on IsPackage change

JavaScript
/* Test type management */
    $(document).on('change', '#package-checkbox', function () {
        var isPackage = $(this).is(":checked");
        var datapointFlaggingCheckbox = $('#datapoint-flagging-checkbox');
        var datapointFlaggingHidden = $('#datapoint-flagging-checkbox');

        if (isPackage) {
            datapointFlaggingCheckbox.prop('disabled', false);
            datapointFlaggingHidden.prop('checked', datapointFlaggingCheckbox.is(":checked"));
        }
        else {
            datapointFlaggingCheckbox.prop('checked', true);
            datapointFlaggingCheckbox.prop('disabled', true);
            datapointFlaggingHidden.prop('checked', datapointFlaggingCheckbox.is(":checked"));
        }
    });
Posted
Updated 29-Apr-20 8:31am
v2

1 solution

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:
Razor
<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:
JavaScript
$(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:
C#
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.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900