KendoValidation with Remote validation

911 Views Asked by At

This is almost killing me. I've never wasted so much time on an issue. I've got a field that needs to be validated with a call to a REST API since it needs to check the presence of some data on the DB. The problem I've is that calling the validator.validate returns true even if the call to json api returns false.

Here's the code (I use the Kendo MVC helpers but it's not related to that the problem)

<div id="divValidator1">
<div class="form-group">
    @Html.LabelFor(m => m.Email)
    @(Html.Kendo().TextBoxFor(m => m.Email)
          .HtmlAttributes(new { placeholder = "[email protected]", type = "email", @class = "k-textbox required",data_bind="value: XXX" })
    )
</div>

<footer class="col-xs-12 form-group text-right">
    @(Html.Kendo().Button()
          .Name("Next1")
          .Content("Next")
          .HtmlAttributes(new { @class = "k-primary", data_bind = "enabled: isEnabled" })
          .Events(ev => ev.Click("onNextClick")))
</footer>

var kendoValid = $("#divValidator1").kendoValidator({
    validateOnBlur: false,
     rules: {
            remote: function (input) {
                if (input.val() == "" || !input.attr("data-val-remote-url")) {
                    return true;
                }

                if (input.attr("data-val-remote-recieved")) {
                    input.attr("data-val-remote-recieved", "");
                    return !(input.attr("data-val-remote"));
                }

                var url = input.attr("data-val-remote-url");
                var postData = {};
                postData[input.attr("data-val-remote-additionalfields").split(".")[1]] = input.val();

                var validator = this;
                var currentInput = input;
                input.attr("data-val-remote-requested", true);
                $.ajax({
                    url: url,
                    type: "POST",
                    data: JSON.stringify(postData),
                    dataType: "json",
                    traditional: true,
                    async:false,
                    contentType: "application/json; charset=utf-8",
                    success: function (data) {

                        if (data == true) {
                            input.attr("data-val-remote", "");
                        }
                        else {
                            input.attr("data-val-remote", false);
                        }
                        input.attr("data-val-remote-recieved", true);
                     //   validator.validateInput(currentInput);


                    },
                    error: function () {
                        input.attr("data-val-remote-recieved", true);
                        validator.validateInput(currentInput);
                    }
                });
                return true;
            }
        },
        messages: {
            remote: function (input) {
                return input.attr("data-val-remote");
            }
        }
}).data("kendoValidator");

var viewModel1 = kendo.observable({
    XXX:null,
        isEnabled: function () {

            var self = this;

            self.get("XXX");

            var x = $("#divValidator1").data("kendoValidator");

            console.log(x.validate());
        }
    });

    kendo.bind($("#divValidator1"), viewModel1);

and here's the controller

public ActionResult IsEmailJustPresent(string email)
    {
        var res = email == "something";

        return Json(res, JsonRequestBehavior.AllowGet);
    }

And the ViewModel

 public class RegisterViewModel
{
    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    [Remote("IsEmailJustPresent", "Home")]
    public string Email { get; set; }
}

I've also used a kendo.observable so that I can enable/disable the next button based on the validation value.

In the isEnabled function you see I do var x = $("#divValidator1").data("kendoValidator"); but it returns always true (seems to only check for the required attribute).

To reach that solution I started from here

If you want there's a more complex example I've created on git that includes the wizard I'll need in my final project

2

There are 2 best solutions below

0
GaloisGirl On

Could this commented line be the problem?

//   validator.validateInput(currentInput);

Is the attribute "data-val-remote" correctly set?

0
Nicholas Piasecki On

I realize this is old, but it seems that Kendo Validator simply does not support asynchronous validation. The promise object returned is truthy and that's why it shows up as valid.

My workaround was to separately trigger the asynchronous call, and then set a property on the dataset on the input to indicate validity. Then, the custom Kendo Validator rule simply synchronously looks for the presence of the value in the dataset.