Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC unobtrusive validation - Custom validator that depends on a previous selection

I have a standard address form with a number of fields. e.g.

  • Address line 1
  • Address line 2
  • Country
  • State
  • Postal code

The problem is that the "state" field should be a required field only when "country" is set to USA. If the country is set to anything else, then it should not be required. I could handle it in the controller but I'd like to do it on the client side unobtrusively. Any suggestions?

like image 339
IanS Avatar asked Dec 26 '22 08:12

IanS


1 Answers

Just wrote a quick demo for your requirement.

// model
public class Address
{
    public int Id { get; set; }
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }

    [Required]
    public string Country { get; set; }

    [RequiredIfCountryIsUSA]
    public string State { get; set; }
    public string PostCode { get; set; }
}


// Validation Attribute
public class RequiredIfCountryIsUSA : ValidationAttribute, IClientValidatable
{
    public RequiredIfCountryIsUSA()
    {

    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        var countryPropertyInfo = validationContext.ObjectInstance.GetType().GetProperty("Country");
        var countryValue = countryPropertyInfo.GetValue(validationContext.ObjectInstance, null).ToString();
        if (countryValue == "USA" && (value == null || string.IsNullOrEmpty(value.ToString().Trim())))
        {
            return new ValidationResult("State is required when Country is USA");
        }

        return ValidationResult.Success;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule();
        rule.ErrorMessage = "State is required when country is USA";
        rule.ValidationParameters.Add("country", "USA");
        rule.ValidationType = "iscountryusa";

        yield return rule;
    }
}

client side javascript

(function ($) {
$.validator.addMethod("iscountryusa", function (state, element, country) {
    var country = $('#Country').val();

    if (country == 'USA' && state == '') {
        return false;
    }

    return true;
});

$.validator.unobtrusive.adapters.addSingleVal("iscountryusa", "country");
} (jQuery));
like image 73
Larry Avatar answered May 01 '23 11:05

Larry