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