Conditional Validation Rules


#1

Is there an easier way than the when clause when adding conditional validation rules? For example, I would like to do something like this

private setupValidation() {
    ValidationRules.off(this.user);
    ValidationRules
      .ensure((c: IEnterpriseLocationUser) => c.title).maxLength(250).required()
      .ensure((c: IEnterpriseLocationUser) => c.contactPhone).minLength(10).maxLength(25).required()
      .on(this.user);

    if (this.isNewUser) {
      ValidationRules
        .ensure((c: IEnterpriseLocationUser) => c.emailAddress).required().email()
        .ensure((c: IEnterpriseLocationUser) => c.userName).required().maxLength(50)
        .ensure((c: IEnterpriseLocationUser) => c.salutationId).required()
        .ensure((c: IEnterpriseLocationUser) => c.firstName).required().maxLength(50)
        .ensure((c: IEnterpriseLocationUser) => c.lastName).required().maxLength(50)
        .on(this.user);
    }
    
    Promise.resolve(true)
      .then(() => this.vc.validate());
  }

However, when I do this, the rules inside the if block overwrite the “main” rules.

As a side note as to why I am approaching it this way, the when clause, to me at least, is hard to follow. For example, does the following mean that the email address field is required when it is a new user? Or when it is a new user, it needs to be be an email address with a minimum length of 10?

.ensure((c: IEnterpriseLocationUser) => c.emailAddress).required().when(x => this.isNewUser).email().minLength(10)


#2

I just ran through this myself.
Hopefully this helps.

There is a way to create different rule sets and then apply them as needed.

Works something like this.

Create your rule set just as if you would apply it to the model as your doing with two changes.
Set a property to contain the ruleset, and instead of using .on to attach the rules to the model, you use .rules to create a set of rules you can apply to a model.

Something like this in TypeScript (not tested, I just stripped out some stuff from my code):

	this.ruleSet1 = 
        ValidationRules
            .ensure('prop1').required()
            .ensure('prop2').required()
            .ensure('prop3').satisfies((v, o: MyClass) =>
            {
                return o.prop3; //check that its true
            })
            .rules;
            //.on(this.model);
			
	this.ruleSet2 = 
        ValidationRules
            .ensure('propA').required()
            .ensure('propB').required()
            .rules;
            //.on(this.model);

You would then use your conditional statement to add what you need:

	if (this.isStudent)
	{
		this.vcontroller.addObject(this.model, this.ruleSet1);
		this.vcontroller.addObject(this.model, this.ruleSet2);
	}
	else
	{
		this.vcontroller.addObject(this.model, this.ruleSet1);
	}

vcontroller is setup in the constructor in my case, something like :

	constructor(private vcf: ValidationControllerFactory)
    {
        this.vcontroller = vcf.createForCurrentScope();
        this.vcontroller.validateTrigger = validateTrigger.changeOrBlur;
    }

#3

Thank you! And the sad thing is I knew this at some point :slight_smile: