1

I am using ASP.NET MVC with Unobtrusive js and it's running perfectly fine but I want to set a rule of Validation for something like this:

I have dropdownlist with two values "Yes" and "No". I have one textbox as well.

Based on selection of the values from dropdownlist if

"Yes" I want to validate that textbox value entered or not using Unobtrusive at client side with server side as well and if

"No" than no validation should work I mean it's ok if textbox value blank or whatever the values entered because I don't want to store that value if dropdownlist value is No no validation should work on that textbox.

Please someone help me out with this problem.

I have already refer so many stackoverflow questions and answers it's pretty good answers too there as well but I am not able to put those to get my solution.

I got the values of dropdown selection in bool i.e.

 public bool IsTestUnit { get; set; }
    [RequiredIfUniTestIsYes("IsTestUnit == true", true, ErrorMessage = "Please Enter Test Unit Job Order Number ")]
        public long TestUnitJobOrder { get; set; }

The code that I have tried:

 public class RequiredIfUniTestIsYes : ValidationAttribute, IClientValidatable
    {
        public RequiredIfUniTestIsYes()
        {

        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var countryPropertyInfo = validationContext.ObjectInstance.GetType().GetProperty("IsTestUnit");
            var countryValue = countryPropertyInfo.GetValue(validationContext.ObjectInstance, null).ToString();
            if (countryValue == "True" && (value.ToString().Trim() == "" || Convert.ToInt32(value) == 0))
            {
                return new ValidationResult("Please Enter Unit Test Job Order Number");
            }

            return ValidationResult.Success;
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule();
            rule.ErrorMessage = "Please Enter Unit Test Job Order Number";
            rule.ValidationParameters.Add("istestunit", "true");
            rule.ValidationType = "isunittest";

            yield return rule;
        }
    }

Javascript:

$.validator.addMethod("isunittest", function (state, element, country) {
                 var country = $('#WorkOderDetailViewModel_IsTestUnit').val();
                     if (country == 'True' && state == '') {
                         return false;
                     }
                     return true;
                 });

             $.validator.unobtrusive.adapters.addSingleVal("isunittest", "true");

             (function ($) {
                 $.validator.addMethod('customRequire', function (value, element) {
                     // your validation logic here
                     return true; // true if valid, otherwise false 
                 });
                 $.validator.unobtrusive.adapters.add('customRequire');
             })(jQuery);

I have just copy paste the code and do not change the name so please ignore those mistake.

13
  • Please post what you've tried !. Commented Nov 23, 2016 at 7:24
  • Consider a foolproof [RequiredIf] or similar validation attribute Or you can write your own - The Complete Guide To Validation In ASP.NET MVC 3 - Part 2 Commented Nov 23, 2016 at 7:25
  • @StephenMuecke I do not have permission to use extra or third party code sir. Commented Nov 23, 2016 at 7:26
  • Then write your own! Commented Nov 23, 2016 at 7:27
  • 1
    Read the 2nd link I gave you. Commented Nov 23, 2016 at 7:33

1 Answer 1

2

Given that you render the fields as below:

@Html.DropDownListFor(m => m.IsTestUnit,
new[] { true, false }.Select(b => new SelectListItem { Text = b ? "Yes" : "No", Value = b.ToString().ToLower() }),
new { id = "WorkOderDetailViewModel_IsTestUnit" })

@Html.TextBoxFor(m => m.TestUnitJobOrder)
@Html.ValidationMessageFor(m => m.TestUnitJobOrder)

with the model properties declared as:

    public bool IsTestUnit { get; set; }

    [RequiredIfUniTestIsYes("IsTestUnit", ErrorMessage = "Please Enter Test Unit Job Order Number ")]
    public long? TestUnitJobOrder { get; set; }

You can define a custom validator like this:

public class RequiredIfUniTestIsYes : ValidationAttribute, IClientValidatable
{
    private string _dependency;

    public RequiredIfUniTestIsYes(string dependency)
    {
        _dependency = dependency;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var countryPropertyInfo = validationContext.ObjectInstance.GetType().GetProperty(_dependency);
        var countryValue = (bool)countryPropertyInfo.GetValue(validationContext.ObjectInstance, null);
        var number = default(long);
        if (countryValue && (value == null || !long.TryParse(value.ToString(), out number)))
        {
            return new ValidationResult("Please Enter Unit Test Job Order Number");
        }

        return ValidationResult.Success;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule();
        rule.ErrorMessage = "Please Enter Unit Test Job Order Number";
        rule.ValidationParameters.Add("istestunit", "true");
        rule.ValidationType = "isunittest";

        yield return rule;
    }
}

And register client-side unobtrusive validation like this:

    $.validator.unobtrusive.adapters.add("isunittest", ['istestunit'], function(options){
        options.rules['isunittest'] = options.params;
        options.messages['isunittest'] = options.message;
    });    
    $.validator.addMethod('isunittest', function (state, element, params) {
        var country = $('#WorkOderDetailViewModel_IsTestUnit').val();
        if (country == 'true' && state == '') {
            return false;
        }
        return true;
    });
Sign up to request clarification or add additional context in comments.

9 Comments

it gives me validation error in both cases in Yes and in No both.
@padhiyar, you meant the validation failed even when you entered nothing and No was selected?
Yes exactly I want validation only If I choose Yes in selection, Validation must not fire when I choose No.
Did you render dropdown like the one in my example: @Html.DropDownListFor(m => m.IsTestUnit, new[] { true, false }.Select(b => new SelectListItem { Text = b ? "Yes" : "No", Value = b.ToString().ToLower() }), new { id = "WorkOderDetailViewModel_IsTestUnit" }) and the respective condition in JS: if (country == 'true' && state == '') { ?
That's weird 'cause those code snippets have been tested and ran well.
|

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.