MVC 3 specifying validation trigger for Remote validation [duplicate]

不羁岁月 提交于 2020-01-22 15:07:04

问题


I have implemented remote validation using MVC 3 unobtrusive validation as follows

The model

public class MyViewModel {
    [Remote("ValidateAction", "Validation")]
    public string Text { get; set; }
}

The Controller

public partial class ValidationController : Controller
{
    public virtual JsonResult ValidationAction(string aTextToValidate)
    {
        if(aTextToValidate == /* some condition */)
            return Json(true, JsonRequestBehavior.AllowGet);
        return Json("This is not valid, Try Again !", JsonRequestBehavior.AllowGet);
    }
}

The View

@using (Html.BeginForm() {
    @Html.TextBoxFor(m => m.Text)
    @Html.ValidationMessageFor(m => m.Text)
}

And that's it, it all works, but ValidationAction is fired on every key press, which is not ideal, I would like just to fire when the element looses focus, but cannot figure how to do this

UPDATE

Actually I have noted that, by default, the validation does fire onBlur once .i.e. the first time the element looses focus, however when attempting to correct it, validation then fires onKeyUp. I think this is intended functionality and thinking about it is probably quite useful. However it would be useful to know if it is possible to modify this behaviour


回答1:


Try

$.validator.setDefaults({ onkeyup: false });

It works for me.




回答2:


Although I think unobtrusive validation are not made for this (the purpose is to validate input in every key press- it kind of user friendly), but there is a workaround for this approach:
You can add these very few lines(mark by //this is my code) to your jquery.validate.js and minify it OR you may create a new .js file and add the fallowing code.
Note that, if you want to get rid of onkeyup for some specific input (not for some specific rule i.e. remote) there is a specific and easy way to do that where you can find it in jquery site.
This code will only ignore remote rule for keyup event and validate others (i.e. required) normally on keyup and focuseout events.

(function ($) {
 jQuery.validator.setDefaults({
    onkeyup: function (element) {
        $(element).data('firedON', 'keyup')    //this is my code
        if (element.name in this.submitted || element == this.lastElement) {
            this.element(element);
        }
    }
});

$.validator.methods.remote = function (value, element, param) {
    if ($(element).data('firedON') == 'keyup') {
       $(element).data('firedON') = '';
       return "dependency-mismatch";           //this 'if' is my code(thats it)
    }
    if (this.optional(element))
        return "dependency-mismatch";

    var previous = this.previousValue(element);
    if (!this.settings.messages[element.name])
        this.settings.messages[element.name] = {};
    previous.originalMessage = this.settings.messages[element.name].remote;
    this.settings.messages[element.name].remote = previous.message;

    param = typeof param == "string" && { url: param} || param;

    if (previous.old !== value) {
        previous.old = value;
        var validator = this;
        this.startRequest(element);
        var data = {};
        data[element.name] = value;
        $.ajax($.extend(true, {
            url: param,
            mode: "abort",
            port: "validate" + element.name,
            dataType: "json",
            data: data,
            success: function (response) {
                validator.settings.messages[element.name].remote = previous.originalMessage;
                var valid = response === true;
                if (valid) {
                    var submitted = validator.formSubmitted;
                    validator.prepareElement(element);
                    validator.formSubmitted = submitted;
                    validator.successList.push(element);
                    validator.showErrors();
                } else {
                    var errors = {};
                    var message = (previous.message = response || validator.defaultMessage(element, "remote"));
                    errors[element.name] = $.isFunction(message) ? message(value) : message;
                    validator.showErrors(errors);
                }
                previous.valid = valid;
                validator.stopRequest(element, valid);
            }
        }, param));
        return "pending";
    } else if (this.pending[element.name]) {
        return "pending";
    }
    return previous.valid;
}
} (jQuery));  

UPDATE
The code above works for sure but I want to notice that I try to make the code more neat by not bringing whole function, ie:

var remote = $.validator.methods.remote;
$.validator.methods.remote = function(a,b,c){
   if ($(element).data('firedON') == 'keyup') return "dependency-mismatch";
   return remote(a,b,c);
}

but it failed because after storing old function in local remote variable, 'this' will referring to somewhere else, I was unable to to fix this on this code so I bring above code.



来源:https://stackoverflow.com/questions/4798855/mvc-3-specifying-validation-trigger-for-remote-validation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!