Core 5 Razor Pages - How to combine server side with client side validation

Occasional Contributor

I'm starting to explore the Core 5 Razor Pages and have come across the following issue:

I have created a testing Razor Page, where i have the following PageModel:

    [PageRemote(
        ErrorMessage = "!!! Duplicate Email Address !!!",
        AdditionalFields = "__RequestVerificationToken",
        HttpMethod = "post",
        PageHandler = "CheckEmail"
    )]
    [BindProperty]
    public string Email { get; set; }

    [Required]
    [BindProperty]
    public string SomeText { get; set; }

And have also created the validation method:

    public JsonResult OnPostCheckEmail()
    {
        var existingEmails = new[] { "Email address removed", "Email address removed", "Email address removed" };
        var valid = !existingEmails.Contains(Email);
        return new JsonResult(valid);
    }

On the cshtml file, i have the following structure:

  <form name="itemForm" id="itemForm" method="post">
        <div class="form-group">
            <label for="Email">Email</label>
            <input asp-for="Email" />
            <span asp-validation-for="Email"></span><br>
        </div>

        <div class="form-group">
            <label for="SomeText">Some Text</label>
            <input asp-for="SomeText" />
            <span asp-validation-for="SomeText"></span><br>
        </div>    

        <div class="form-group">
            <label for="river1">river1</label>
            <input checked="checked" data-val="true" data-val-required="The     river1 field is required." id="river1" name="river1" type="checkbox" value="true" class="require-one" />
            <input name="river1" type="hidden" value="false" /><br />
        </div>
        <div class="form-group">
            <label for="river2">river2</label>
            <input checked="checked" data-val="true" data-val-required="The river2 field is required." id="river2" name="river2" type="checkbox" value="true" class="require-one" />
            <input name="river2" type="hidden" value="false" /><br />
        </div>
        <div class="form-group">
            <label for="river3">river3</label>
            <input checked="checked" data-val="true" data-val-required="The river3 field is required." id="river3" name="river3" type="checkbox" value="true" class="require-one" />
            <input name="river3" type="hidden" value="false" /><br />
        </div>

        <input id="btnSubmit" name="btnSubmit" type="submit" value="submit" />
    </form>

And I have the following code inside the scripts section:

    @section Scripts {
            @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}

            <script>
           
                $(document).ready(function () {

                    $.validator.addMethod('require-one', function (value) {
                        return $('.require-one:checked').length > 0;
                    }, 'Please check at least one box.');

                    $.validator.unobtrusive.adapters.add('require-one', function (options) {

                        if (options.message) {
                            options.messages['require-one'] = options.message;
                        }

                    });

                    var checkboxes = $('.require-one');
                    var checkbox_names = $.map(checkboxes, function (e, i) {
                        return $(e).attr("name")
                    }).join(" ");

                    $("#itemForm").validate({
                        groups: {
                            checks: checkbox_names
                        },
                        errorPlacement: function (error, element) {
                            if (element.attr("type") == "checkbox") {
                                error.insertAfter(checkboxes.last());
                            } else {
                                error.insertAfter(element);
                            }
                        }
                    });

                    $("#btnSubmit").on("click", function (e) {

                        if ($("#itemForm").valid()) {
                            $("#itemForm").submit();
                            return true;
                        } else {
                            e.preventDefault();
                            return false;
                        }
                    });

                });

            </script>

    }

The issue is that with the JS code inside the $(document).ready function, the server side validation does not work and the check box validation, which is requesting that at least one of the checkboxes be set to checked, works perfectly.

But if I remove the $(document).ready function wrapping, and leave the code directly on the root, the server side validations work perfectly, correctly validating the the email inserted as unique (or not) and requiring that something is written inside the 'sometext' field, while at the same time the checkboxes validation no longer works.

What am I doing wrong? How can I have both validations, server and client side, working at the same time?

Help please?

0 Replies