问题
I have the following custom attribute that is used to validate if an array has had a value submitted:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public sealed class RequiredArrayAttribute : RequiredAttribute, IClientValidatable
{
public RequiredArrayAttribute()
: base()
{
}
public override bool IsValid(object value)
{
var list = (IList)value;
if (list != null && list.Count > 0)
{
return true;
}
return false;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
string errorMessage = this.ErrorMessage;
// Get the specific error message if set, otherwise the default
if (string.IsNullOrEmpty(errorMessage) && metadata != null)
{
errorMessage = FormatErrorMessage(metadata.GetDisplayName());
}
var clientValidationRule = new ModelClientValidationRule()
{
ErrorMessage = errorMessage,
ValidationType = "requiredarray"
};
return new[] { clientValidationRule };
}
}
Applied to
[RequiredArray(ErrorMessage = "Please select at least one product")]
public IEnumerable<string> ProductIds { get; set; }
And the following js (included after jquery.js, unobtrusive-ajax.js, validate.js and validate.unobtrusive.js)
(function ($) {
$.validator.addMethod('requiredarray', function (value, element, params) {
var selector = 'input[name=' + $(element).attr('name') + ']:checked';
return $(selector).length > 0;
}, 'Clientside Should Not Postback');
$.validator.unobtrusive.adapters.addBool('requiredarray');
})(jQuery);
I have tried changing the addMethod to just return false; but this still does nothing (and no errors in my console)
I was wondering if anyone could spot anything I had done wrong with the above code. I have done a similar thing with an address attribute and it works just fine but for some reason I can't get this one to work?
Further to this the server side validation works.
Razor code for validation message
@Html.ValidationMessageFor(m => m.ProductIds)
Example html for rendered checkboxes:
<input type="checkbox" class="checkbox" name="ProductIds" value="EXAMPLEID1234" id="checkbox-1" checked="checked" />
<input type="checkbox" class="checkbox" name="ProductIds" value="EXAMPLEID1235" id="checkbox-2" checked="checked" />
EDIT
further to this I can now get the clientside validation to work using the following
$.validator.addClassRules('required-group', { 'requiredarray': true });
instead of the validator.unobtrusive.adapters.addBool method in the above. I have also added the class required-group to the checkbox
However, if I use this it doesn't add the proper MVC Error message, just the Clientside Should Not Postback as set in the above code. I have tried adding the following attributes to the checkbox:
data-val="true" data-val-required="Please select at least one sample"
and also tried using data-val-requiredarray but this makes no difference so does anyone know how to change the above clientside rules to make it use the MVC error message
回答1:
So this was fixed with the following changes to the html:
<input type="checkbox" class="checkbox required-group" name="ProductIds" value="EXAMPLEID1234" id="checkbox-1" checked="checked" data-val-required="Please select at least one sample" />
<input type="checkbox" class="checkbox required-group" name="ProductIds" value="EXAMPLEID1235" id="checkbox-2" checked="checked" />
data-val-required only needs to be on the first checkbox in the array. Then using the following jQuery:
(function ($) {
$.validator.addMethod('requiredarray', function (value, element, params) {
return $('input[name=' + $(element).attr('name') + ']:checked').length > 0;
}, 'Please select at least one');
$.validator.addClassRules('required-group', { 'requiredarray': true });
var errorMessage = $('.required-group').eq(0).data('val-requiredarray');
if (errorMessage && errorMessage !== "") {
$.validator.messages.requiredarray = errorMessage;
}
})(jQuery);
I have changed the addBool to addClassRules and then used $.validator.messages to set the error message.
来源:https://stackoverflow.com/questions/24368156/custom-clientside-validation-for-required-at-least-one-in-array