4

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?

IanS
  • 315
  • 3
  • 12
  • pls send your View page code – Amit May 30 '14 at 11:03
  • 1
    You could implement `IValidatableObject`. See [here](http://stackoverflow.com/questions/17970584/conditional-validation-on-model-in-mvc) and all over the Internet and SO for an example. – Andrei V May 30 '14 at 11:15

4 Answers4

6

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));
Larry
  • 2,172
  • 2
  • 14
  • 20
2

Check out MVC Foolproof. http://foolproof.codeplex.com/. You can NuGet the package into your solution.

It has attributes such as these which may help you;

[RequiredIf]
[RequiredIfNot]
[RequiredIfTrue]
[RequiredIfFalse]
[RequiredIfEmpty]
[RequiredIfNotEmpty]
[RequiredIfRegExMatch]
[RequiredIfNotRegExMatch]
richardb
  • 943
  • 1
  • 10
  • 27
2

You need to create a custom validation attribute, deriving from ValidationAttribute. Take the name of the dependent property (in this case, Country) as a parameter for the constructor, and override the IsValid method, in which you will specify the validation logic which will use this dependent property.

Now, if you also want to enable this validation unobtrusively on client-side, you need to implement the IClientValidatable interface in your custom validation attribute, and then you will need to write the same validation logic in a JavaScript method. Also, you will need to add this method to the list of jQuery unobtrusive validation adapters.

You can read up more here, here, and here.

Community
  • 1
  • 1
Bhushan Shah
  • 1,028
  • 8
  • 20
0

I make it simple using js file. I created the Js file named it as "CountryValidate.js" and written like this

var list = ["India", "Australia", "Pakisthan"];
 $(document).ready(function(){
        debugger
        $("#Country").keyup(function () {
            debugger
            for (var i = 0; i < list.length; i++) {
                if ($("#Country").val() !== list[i]) {
                    $("#error").show();
                }
                else {
                    $("#error").hide();
                    break;
                }
            }

        });
    });

and added some statements in the view(Student.cshtml) I added the this property for the Country Name Text Box

<span class="validation has-error text-danger" id="error" hidden>Invalid Country Name</span> 

The Changes i made it for the Textbox to display the validation message.