Custom clientside validation for required at least one in array

两盒软妹~` 提交于 2019-12-10 11:06:14

问题


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

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