I have an Angular 2 Reactive form using FormGroup. I need to compare the values of two fields, so I am passing a validator to the FormGroup upon creation. The validation works great:
this.form = this.formBuilder.group({
add: this.formBuilder.group({
mobile: ['', [
Validators.required,
this.duplicate
]],
voice: [false]
}),
existing: this.formBuilder.array([])
}, {validator: this.validateDuplicates});
validateDuplicates(group: FormGroup): any {
let adding = group.get('add').get('mobile').value;
if (!adding) {
return null;
}
let matches: boolean[] = (group.get('existing') as FormArray).controls
.map(control => {
return control.get('number').value;
})
.filter(val => val === adding);
return matches.length > 0 ? {
duplicate: {adding}
} : null;
}
After I enter an invalid value, the form.errors.duplicate field is populated correctly, and the form group is marked with an ng-invalid
CSS class in the DOM.
The only gap I have is that I would like a specific form control to be marked as ng-invalid
when this group-level validator fails. Is there any way to do that? I have tried messing with the object returned from the validator function to match the nested layer of the target form control, to no avail.
In the short term I have been able to work around it by adding additional markup and styling on a specific element when the form is invalid, but ideally I would like to be able to get rid of that, and address specific error codes in the markup for that control only, rather than going up to the parent form group level:
<md-input-container class="primary" floatPlaceholder="never">
<input mdInput name="mobile" type="text" pattern="^\([0-9]{3}\)\s[0-9]{3}\-[0-9]{4}$" placeholder="Number" formControlName="mobile" required>
<md-hint *ngIf="!addControl.touched && addControl.invalid" align="start" color="warn">(202) 555-5555</md-hint>
<md-hint *ngIf="addControl.touched && addControl.invalid" align="end" color="warn">Format must be (###) ###-####</md-hint>
<!-- Workaround I'd like to remove -->
<md-hint *ngIf="form.errors && form.errors.duplicate">Numbers must be unique</md-hint>
</md-input-container>
reactive forms
the recommended way (and maybe the right one) to add validators is in component, not in template.. so in your case, Pattern and required must go only in component. Also, there-s md-error in Material2 that you can use to show errors. Now about your problem, a plunker to demonstrate it would be good. – developer033