Vinod Jangle Ответов: 1

Html.checkboxfor возвращает ложное значение при его отключении?


Привет,

У меня есть два Html.CheckBoxFor с именами IsPackage и IsDataPoint.

Когда IsPackage проверен, то IsDataPoint также может быть проверен и доступен для пользователя, чтобы выбрать значение.

Когда IsPackage снят, IsDataPoint также должен быть проверен и отключен. Вот в чем заключается проблема, когда IsDataPoint отключен, он всегда дает ложное значение для управления при отправке формы.

Я попытался добавить скрытое поле для IsDataPoint, но оно все еще не сохраняет состояние значения.

Что я уже пробовал:

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


Я также попытался установить скрытое значение поля при изменении IsPackage

/* 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"));
        }
    });

1 Ответов

Рейтинг:
0

Richard Deeming

Отключенный HTML-элемент не отправляется на сервер при отправке формы.
отключено - HTML: язык разметки гипертекста | MDN[^]

Чтобы еще больше усложнить ситуацию, CheckBoxFor и CheckBox помощники автоматически отображают скрытый ввод с тем же именем, со значением, установленным в "false" Это делается для устранения того факта, что непроверенный флажок ничего не отправляет на сервер при отправке . (Код привязки модели автоматически удаляет это дополнительное значение, если флажок установлен и включен.)
AspNetWebStack/InputExtensions.cs at 749384689e027a2fcd29eb79a9137b94cea611a8 · aspnet/AspNetWebStack · GitHub[^]

Но вы можете использовать этот дополнительный скрытый вход для решения проблемы.

Начните с упрощения вашего представления:

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

Затем попросите ваш 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();
});

Я бы также рекомендовал изменить способ использования вашей модели, чтобы это условие применялось как на сервере, так и на клиенте:
public class YourViewModel
{
    public bool IsPackage { get; set; }
    public bool IsDataPoint { get; set; }
    internal bool IsReallyDataPoint => IsPackage || IsDataPoint;
}
В любом месте кода на стороне сервера, где вы хотите проверить, является ли модель точкой данных, используйте IsReallyDataPoint вместо этого собственность.