2

How to fire a custom validator in client side? This is what i have till now:

My validation class:

public class AlmostEqual : ValidationAttribute, IClientValidatable
{
    private readonly string _otherProperty;
    private readonly float _myPercent;
    public AlmostEqual(string otherProperty,float percent)
    {
        _otherProperty = otherProperty;
        _myPercent = percent;
    }


    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var property = validationContext.ObjectType.GetProperty(_otherProperty);

        var otherPropertyValue = property.GetValue(validationContext.ObjectInstance, null);

        dbEntities db = new dbEntities();
        Metal metal = db.Metals.Find(Convert.ToInt32(otherPropertyValue));

        double _unitWeight = metal.UnitWeight;
        double _percent = metal.UnitWeight * (_myPercent / 100);

        double myProperty = double.Parse(value.ToString());

        bool result = myProperty >= _unitWeight - _percent && myProperty <= _unitWeight + _percent;

        if (!result)
        {
             return new ValidationResult(string.Format(
                    CultureInfo.CurrentCulture,
                    FormatErrorMessage(validationContext.DisplayName),
                    new[] { _otherProperty }
                ));
        }


        return null;
    }


    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
            ValidationType = "almostequal",
        };
        rule.ValidationParameters.Add("other", _otherProperty);
        yield return rule;
    }


}

Code from Metdata class:

        [Required]           
        [AlmostEqual("IDMetal",5,ErrorMessage="Weight do not correspond with dimensions.")]
        public Nullable<double> UnitWeight { get; set; }
    }

In view I added this js:

<script type="text/javascript">
      $.validator.unobtrusive.adapters.addBool("almostequal", "Range");
</script>

My webconfig contains:

 <add key="ClientValidationEnabled" value="true" />
 <add key="UnobtrusiveJavaScriptEnabled" value="true" />

I get the error:

Uncaught TypeError: Cannot read property 'call' of undefined in file jquery.validate.min.js at line 27

POIR
  • 3,110
  • 9
  • 32
  • 48
  • 1
    Please take a look at: http://stackoverflow.com/questions/4747184/perform-client-side-validation-for-custom-attribute/4747466 – Siva Gopal Sep 10 '14 at 09:43
  • 1
    The link is from this post. – POIR Sep 10 '14 at 09:45
  • Sorry about that, updated the correct URL – Siva Gopal Sep 10 '14 at 09:48
  • But I don't understand why we should create a javascript function when we have a class that make our validation. – POIR Sep 10 '14 at 11:39
  • That is the reason, the client side JavaScript function is called the adapter. It works to transform your server validation stuff to the client side. Unfortunately no direct way to transform your server behavior to client side. – Siva Gopal Sep 10 '14 at 12:02

1 Answers1

1

Take a look at this: http://thewayofcode.wordpress.com/tag/custom-unobtrusive-validation/

The only difference I can spot in your code is the way you created the $.validator.unobtrusive.adapters.addBool function. The parameters are a little bit different but, maybe, the problem is just that you have not defined the rule part of your adapter.

Try using something like this:

$.validator.unobtrusive.adapters.add("almostequal", function (options) {
    options.rules["almostequal"] = "#" + options.element.name.replace('.', '_'); // mvc html helpers
    options.messages["almostequal"] = 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.