1

I am trying to write a very simple Data Annotation Validator for my ASP.NET MVC viewmodel. When applied on a datetime field, the validator must check whether the year of the date is the current year or not. Server side works as intented, but client side doesn't seem to trigger (other validators like range or required work)

Server Side:

class CurrentYearAttribute : ValidationAttribute, IClientValidatable
{
    public override bool IsValid(object value)
    {
        if(value == null)
        {
            return false;
        }

        var date = (DateTime)value;

        return (date.Year == DateTime.Now.Year);

    }

    public override string FormatErrorMessage(string name)
    {
        return "Le champ " + name + " doit être de l'année en cours.";
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule()
        {
            ValidationType = "currentyear",
            ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
        };

        yield return rule;

    }
}

Client side:

<script type="text/javascript">
        $(document).ready(function () {
            $.validator.addMethod(
                'currentyear',
                function (value, element, params) {
                    alert("hello"); // never 
                    return (Date.parse(value).getFullYear() == (new Date()).getFullYear());
                });

            $.validator.unobtrusive.adapters.addBool("currentyear");

            //$.validator.unobtrusive.parse("form");
        });
</script>

3 Answers 3

2

I believe that you need to call $.validator.addMethod() and $.validator.unobtrusive.adapters.addBool before $(document).ready. If your form elements are inserted dynamically you need to call $.validator.unobtrusive.parse or $.validator.unobtrusive.parseElement on each element.

Sign up to request clarification or add additional context in comments.

Comments

2

Your custom validation functions and adapters are in the jQuery document ready function which is too late in the process. I made this same mistake myself.

I've modified your code just to wrap the setup in a JavaScript closure and pass in the jQuery object aliased to $.

<script type="text/javascript">
        (function ($) {
            $.validator.addMethod(
                'currentyear',
                function (value, element, params) {
                    alert("hello"); // never 
                    return (Date.parse(value).getFullYear() == (new Date()).getFullYear());
                });

            $.validator.unobtrusive.adapters.addBool("currentyear");

            //$.validator.unobtrusive.parse("form");
        } (jQuery));
</script>

Comments

1

The problem is just that you have not defined the rule part of your adapter.

Try using something like this:

$.validator.unobtrusive.adapters.addBool("currentyear", function (options) {
    options.rules["currentyear"] = "#" + options.element.name.replace('.', '_'); // mvc html helpers
    options.messages["currentyear"] = options.message;
});

About the rule :

The jQuery rules array for this HTML element. The adapter is expected to add item(s) to this rules array for the specific jQuery Validate validators that it wants to attach. The name is the name of the jQuery Validate rule, and the value is the parameter values for the jQuery Validate rule.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.