Reputation: 403
I have unobtrusive client-side validation setup for my page. The error messages are returned from our database. For one of the validation messages I needed to add parameters so I can format it with particular values. This works fine server side but I obviously haven't got access to some of these values when the GetClientValidationRules method is first setup. Because of this it looks like I'm going to have to build up the error message in my client-side code but I have no idea on how to do this as you simply return true or false in the jQuery.validator.addMethod.
So what I basically need to be able to do is set ErrorMessage to string.Empty in GetClientValidationRules method, and then in my clinet-side code which is doing the validation be able to return whatever message I want.
Here is the client-side code being wired up in MVC 3.
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var rule = new ModelClientValidationRule
{
ValidationType = "maximumdatecoverrequired",
ErrorMessage = string.Empty,
};
rule.ValidationParameters.Add("maxdate", DateTime.Now.AddDays(Settings.Default.MaximumDateCoverRequiredDaysInFuture).ToString("yyyy/MM/dd"));
return new[] { rule };
}
Here is my client-side code to validate against this particular property.
jQuery.validator.addMethod("maximumdatecoverrequired", function (value, element, params) {
var maxDate = new Date(params["maxdate"]);
var day = maxDate.getDate();
var month = maxDate.getMonth() + 1;
var year = maxDate.getFullYear();
var dateCoverRequired = new Date(value).toString('yyyy/MM/dd');
maxDate = maxDate.toString('yyyy/MM/dd');
if (value > maxDate) {
$("input#DateCoverRequired_Day").val(day);
$("select#DateCoverRequired_Month").val(month);
$("input#DateCoverRequired_Year").val(year);
return false;
}
return true;
});
How do I return a custom message in my client-side code?
Upvotes: 0
Views: 824
Reputation: 14951
Let me give you an example of how to do this. The example I'll choose is registering a new user and checking for their name.
What we're going to do is allow the user to choose a UserName and, if it already exists in the database, we won't let them have it and will make a suggestion.
To do this we'll use Remote validation which points to an ActionMethod in our controller.
Register Model
public class RegisterModel
{
//This is the one I'm giving you the code for...
[Required]
[RegularExpression(@"(\S)+", ErrorMessage = "Username cannot contain spaces.")]
[Remote("CheckUserName", HttpMethod="POST")]
[Display(Name = "Username")]
public string UserName { get; set; }
// You can do this one yourself :-)
[Required]
[Remote("CheckEmailAddress", ErrorMessage="{0} already has an account, please enter a different email address.", HttpMethod="POST")]
[DataAnnotationsExtensions.Email(ErrorMessage="{0} is not a valid email address.")]
[Display(Name = "Email address")]
public string Email { get; set; }
[Required]
[ValidatePasswordLength]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
ActionMethod (the Remote method referenced by the model)
[HttpPost]
[OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
public JsonResult CheckUserName(string userName, Guid? userId = null)
{
if (userName != null || userName.Length > 2)
{
var users = Membership.FindUsersByName(userName);
if (users.Count == 0)
{
return Json(true);
}
else
{
if ((users[userName].ProviderUserKey as Guid?) == userId)
{
return Json(true);
}
else
{
string suggestedUID = String.Format(CultureInfo.InvariantCulture, "{0} is not available.", userName);
// Maybe this is a bit feeble, but it will loop around (inefficiently) and suggest a new username with a number on the end. EG Tom is not available. Try Tom37
for (int i = 1; i < 100; i++)
{
string altCandidate = userName + i.ToString();
if (Membership.FindUsersByName(altCandidate).Count == 0)
{
suggestedUID = String.Format(CultureInfo.InvariantCulture, "{0} is not available. Try {1}.", userName, altCandidate);
break;
}
}
// This is the important bit. I am returning a suggested UserName
return Json(suggestedUID, JsonRequestBehavior.AllowGet);
}
}
}
else
{
return Json(true);
}
}
I think this is pretty cool, because the regular expression makes sure there are no spaces and then (if it's okay) it's submitted to the remote method which checks the database.
Upvotes: 1