I've been trying to use the model form in an Ionic/Angular2. I have a form that I want to do some conditional validation. The user starts with 6 fields that are required and then can choose between 'manual' and 'automatic' processing. If 'automatic' is chosen, 3 more form inputs/selects are rendered. I'd like these 3 fields to go from being not required to required.
Here's the model to start:
this.myForm = this.formBuilder.group({
name: ['', Validators.compose([Validators.required, Validators.maxLength(45), Validators.minLength(2)])],
img: [''],
longDescription: ['', Validators.compose([Validators.required, Validators.maxLength(200)])],
shortDescription: ['', Validators.compose([Validators.required, Validators.maxLength(45)])],
processingType: [this.PROCESSING_TYPE.MANUAL],
discountType: ['' ],
discountRule: ['' ],
discountAmount: ['' ], // money, isNumbersOnly handled by custom validator
product: [''],
dateRuleDays: ['' ],
dateRuleTimeStart: ['' ],
dateRuleTimeEnd: ['' ],
startDate: ['', Validators.required],
expiryDate: ['', Validators.required ]
});
discountType, discountRule, discountAmount are the 3 fields that I'd like to toggle to being required.
Here's what I've tried:
markup where setProcessingType fn gets called (i can provide the full page if needed)
<!-- automatic or manual -->
<h4 margin-top text-center>Processing Type</h4>
<ion-row text-center>
<ion-col width-50>
<button class="width-80" color="primary" (click)="setProcessingType(PROCESSING_TYPE.MANUAL)" ion-button margin-top>{{ PROCESSING_TYPE.MANUAL }}</button>
</ion-col>
<ion-col width-50>
<button class="width-80" color="primary" (click)="setProcessingType(PROCESSING_TYPE.AUTOMATIC)" ion-button margin-top>{{ PROCESSING_TYPE.AUTOMATIC }}</button>
</ion-col>
</ion-row>
setProcessingType gets called when the user clicks between 'manual' and 'automatic' buttons. type: string is the new value that i will set to processingType.
setProcessingType(type: string): void {
this.myForm.patchValue({ // i welcome comments to correct this to 'setValue()' if needed
processingType: type
});
let formCtrls = ['discountType', 'discountRule', 'discountAmount', 'dateRuleDays', 'dateRuleTimeStart', 'dateRuleTimeEnd'];
let add = [Validators.required];
let empty = [];
formCtrls.forEach((key, index) => {
if (this.myForm.controls && this.myForm.controls[key]) {
if (type === this.PROCESSING_TYPE.AUTOMATIC) {
this.myForm.controls[key].setValidators([Validators.required]);
} else {
console.log('resetting validators...');
this.myForm.controls[key].setValidators([]);
console.log('errors on : ', key, this.myForm.controls[key].errors);
// this.myForm.controls[key].markAsUntouched(); // attempt 3928
// this.myForm.controls[key].markAsPristine() // attempt 3929
//this.myForm.controls.updateValueAndValidty(); // this throws an error
}
}
})
console.log('new form controls: ', this.myForm.controls);
}
I've also subscribed to the 'processingType' valueChanges where i ran the same logic as the function above
this.myForm.get('processingType').valueChanges.subscribe(data => this.onProcessingTypeChanged(data));
Here are some screenshots from my logs of the values i'm trying to add a validator to:
The start (how it should be)...
After clicking 'Automatic'...why are they still null?
After clicking 'Manual'... now they are required?
Based on the above suspicion, i suspect
this.myForm.controls.updateValueAndValidty();
or this.myForm.controls[key].updateValueAndValidity();
is the issue, but as I commented within the code, both of those threw 'not a function' errors.
I've googled nearly every combination of conditional validation, angular2 form model, dynamically adding validators, etc... too many links to list here, haha.
Hopefully this is enough for someone to help diagnose the problem.
Thanks in advance.