Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Why am i getting a client side validation for boolean field in a collection list ? #71

Closed
giannik opened this issue Sep 27, 2023 · 2 comments

Comments

@giannik
Copy link

giannik commented Sep 27, 2023

Im getting the following client side error when clicking submit button :

image

viewmodel

    public class AddPartsViewModel
    {
        public AddPartsViewModel()
        {
            PartSelections = new List<PartSelectionViewModel>();
        }

        public EditTypeViewModel Type { get; set; }
        public List<PartSelectionViewModel> PartSelections { get; set; }
    }

    public class PartSelectionViewModel
    {
        public string PartName { get; set; }
        public string PartDisplayName { get; set; }
        public string PartDescription { get; set; }
        public bool IsSelected { get; set; }
    }

view


@model AddPartsViewModel
@{
    int i = 0;
}
<zone Name="Title"><h5>@T["Add Parts To \"{0}\"", Model.Type.DisplayName]</h5></zone>

@T["Choose the Parts to add to this Content Type."]

<form asp-action="AddPartsTo">
    @Html.ValidationSummary()
    <div class="mb-3">
        <ul class="list-group">
            @foreach (var partSelection in Model.PartSelections)
            {
                <li class="list-group-item">
                    <div class="form-check">
                        <input type="checkbox" class="form-check-input" asp-for="PartSelections[i].IsSelected">
                        <label class="form-check-label" asp-for="PartSelections[i].IsSelected">@partSelection.PartDisplayName</label>
                        <span class="form-text">@partSelection.PartDescription</span>
                    </div>
                    <input asp-for="PartSelections[i].IsSelected" type="hidden" />
                    <input asp-for="PartSelections[i].PartName" type="hidden" />
                </li>
                i++;
            }
        </ul>
    </div>
    <div class="mb-3">
        <button class="btn btn-primary save" type="submit">@T["Save"]</button>
        <a class="btn btn-secondary cancel" role="button" asp-route-action="Edit" asp-route-id="@Model.Type.Name">@T["Cancel"]</a>
    </div>
</form>


@dahlbyk
Copy link
Collaborator

dahlbyk commented Sep 28, 2023

The validation failure is caused by this:

<input asp-for="PartSelections[i].IsSelected" type="hidden" />

You don't need to explicitly include that; asp-for automatically appends a hidden input to the form.

I've added a demo to reproduce: #72. Without the explicit hidden the markup looks like this:

<form method="post">
        <div class="form-field">
                <label>
                    <input type="checkbox" data-val="true" data-val-required="The IsSelected field is required." id="Numbers_0__IsSelected" name="Numbers[0].IsSelected" value="true" class="input-validation-valid">
                    One
                </label>
                <input type="hidden" data-val="true" data-val-required="The Name field is required." id="Numbers_0__Name" name="Numbers[0].Name" value="One" class="input-validation-valid">
                <!-- snip -->
            <span class="field-validation-valid" data-valmsg-for="Numbers" data-valmsg-replace="true"></span>
            <em class="results">Selected numbers: </em>
        </div>

        <input type="submit" value="Submit">
    <input name="__RequestVerificationToken" type="hidden" value="...">
    <input name="Numbers[0].IsSelected" type="hidden" value="false" class="input-validation-valid">
    <input name="Numbers[1].IsSelected" type="hidden" value="false" class="input-validation-valid">
    <input name="Numbers[2].IsSelected" type="hidden" value="false" class="input-validation-valid">
</form>

Including it adds an extra hidden that's confusing us:

                <input type="hidden" id="Numbers_0__IsSelected" name="Numbers[0].IsSelected" value="False" class="input-validation-valid">

Specifically we're confused by "False" instead of the auto-generated false:

// Checkboxes do not submit a value when unchecked. To work around this, platforms such as ASP.NET render a
// hidden input with the same name as the checkbox so that a value ("false") is still submitted even when
// the checkbox is not checked. We check this special case here.
if (elementType === "checkbox") {
const checkboxHiddenInput = element.form.querySelector(`input[name='${element.name}'][type='hidden']`);
if (checkboxHiddenInput instanceof HTMLInputElement && checkboxHiddenInput.value === "false") {
return true;
}
}

We could certainly patch that to also allow "False", but that's not necessary for the standard pattern to Just Work.

@giannik
Copy link
Author

giannik commented Sep 28, 2023

I verify that it works. For some reason i had it there before moving from jquery validation

@dahlbyk dahlbyk closed this as completed Sep 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants