Angular form validation: compare two fields in different form groups












4















I'm sorry if it's a duplicate of someone question. I didn't find a solution for my problem.



Can anybody explain or give an example how to compare two fields in one form but in different form groups?



Here is code snippet to see how my form and validator are look like:



private createForm() {

const testGroups = {
groupOne: this.fb.group({
fieldOne: this.fb.control(null)
}),
groupsTwo: this.fb.group({
fieldTwo: this.fb.control(null, [this.matchValidator])
})
};

this.testForm = this.fb.group(testGroups);
}

matchValidator(from: FormControl): ValidatorFn {
return (to: AbstractControl): { [key: string]: any } => {
return from.value && to.value && from.value === to.value
? { fieldMatch: true }
: null;
};
}









share|improve this question

























  • I guess you could use root property of the control

    – Florian
    Nov 22 '18 at 8:03











  • @Florian thanks for reply. Can you provide an example where should I bind validator? Whiat should I pass? And what I should to return (I think it's defenetly not AbstractControl)?

    – hofshteyn
    Nov 22 '18 at 8:05











  • @hofshteyn, give my answer a try.

    – SiddAjmera
    Nov 22 '18 at 8:42
















4















I'm sorry if it's a duplicate of someone question. I didn't find a solution for my problem.



Can anybody explain or give an example how to compare two fields in one form but in different form groups?



Here is code snippet to see how my form and validator are look like:



private createForm() {

const testGroups = {
groupOne: this.fb.group({
fieldOne: this.fb.control(null)
}),
groupsTwo: this.fb.group({
fieldTwo: this.fb.control(null, [this.matchValidator])
})
};

this.testForm = this.fb.group(testGroups);
}

matchValidator(from: FormControl): ValidatorFn {
return (to: AbstractControl): { [key: string]: any } => {
return from.value && to.value && from.value === to.value
? { fieldMatch: true }
: null;
};
}









share|improve this question

























  • I guess you could use root property of the control

    – Florian
    Nov 22 '18 at 8:03











  • @Florian thanks for reply. Can you provide an example where should I bind validator? Whiat should I pass? And what I should to return (I think it's defenetly not AbstractControl)?

    – hofshteyn
    Nov 22 '18 at 8:05











  • @hofshteyn, give my answer a try.

    – SiddAjmera
    Nov 22 '18 at 8:42














4












4








4


1






I'm sorry if it's a duplicate of someone question. I didn't find a solution for my problem.



Can anybody explain or give an example how to compare two fields in one form but in different form groups?



Here is code snippet to see how my form and validator are look like:



private createForm() {

const testGroups = {
groupOne: this.fb.group({
fieldOne: this.fb.control(null)
}),
groupsTwo: this.fb.group({
fieldTwo: this.fb.control(null, [this.matchValidator])
})
};

this.testForm = this.fb.group(testGroups);
}

matchValidator(from: FormControl): ValidatorFn {
return (to: AbstractControl): { [key: string]: any } => {
return from.value && to.value && from.value === to.value
? { fieldMatch: true }
: null;
};
}









share|improve this question
















I'm sorry if it's a duplicate of someone question. I didn't find a solution for my problem.



Can anybody explain or give an example how to compare two fields in one form but in different form groups?



Here is code snippet to see how my form and validator are look like:



private createForm() {

const testGroups = {
groupOne: this.fb.group({
fieldOne: this.fb.control(null)
}),
groupsTwo: this.fb.group({
fieldTwo: this.fb.control(null, [this.matchValidator])
})
};

this.testForm = this.fb.group(testGroups);
}

matchValidator(from: FormControl): ValidatorFn {
return (to: AbstractControl): { [key: string]: any } => {
return from.value && to.value && from.value === to.value
? { fieldMatch: true }
: null;
};
}






angular typescript validation angular-forms reactive-forms






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 '18 at 8:02







hofshteyn

















asked Nov 22 '18 at 7:57









hofshteynhofshteyn

12910




12910













  • I guess you could use root property of the control

    – Florian
    Nov 22 '18 at 8:03











  • @Florian thanks for reply. Can you provide an example where should I bind validator? Whiat should I pass? And what I should to return (I think it's defenetly not AbstractControl)?

    – hofshteyn
    Nov 22 '18 at 8:05











  • @hofshteyn, give my answer a try.

    – SiddAjmera
    Nov 22 '18 at 8:42



















  • I guess you could use root property of the control

    – Florian
    Nov 22 '18 at 8:03











  • @Florian thanks for reply. Can you provide an example where should I bind validator? Whiat should I pass? And what I should to return (I think it's defenetly not AbstractControl)?

    – hofshteyn
    Nov 22 '18 at 8:05











  • @hofshteyn, give my answer a try.

    – SiddAjmera
    Nov 22 '18 at 8:42

















I guess you could use root property of the control

– Florian
Nov 22 '18 at 8:03





I guess you could use root property of the control

– Florian
Nov 22 '18 at 8:03













@Florian thanks for reply. Can you provide an example where should I bind validator? Whiat should I pass? And what I should to return (I think it's defenetly not AbstractControl)?

– hofshteyn
Nov 22 '18 at 8:05





@Florian thanks for reply. Can you provide an example where should I bind validator? Whiat should I pass? And what I should to return (I think it's defenetly not AbstractControl)?

– hofshteyn
Nov 22 '18 at 8:05













@hofshteyn, give my answer a try.

– SiddAjmera
Nov 22 '18 at 8:42





@hofshteyn, give my answer a try.

– SiddAjmera
Nov 22 '18 at 8:42












1 Answer
1






active

oldest

votes


















1














matchValidator will be called by Angular and not by you. So it won't have the access to the Component's this.



So you will have to bind to it.



You can use the get method on a FormGroup to get the group1's field's value: (<FormGroup>this.mainForm.get('group1')).get('field').value



Give this a try:



Component Class:



import { Component } from '@angular/core';
import { FormGroup, FormBuilder, FormControl, ValidatorFn, AbstractControl } from '@angular/forms';

@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
mainForm: FormGroup;

constructor(private fb: FormBuilder) { }

ngOnInit() {
this.mainForm = this.fb.group({
group1: this.fb.group({
field:
}),
group2: this.fb.group({
field: [null, [this.matchValidator.bind(this)]]
})
});

}

matchValidator(control: AbstractControl): { [key: string]: boolean } | null {
const fromValue = control.value;
if(this.mainForm) {
const toValue = (<FormGroup>this.mainForm.get('group1')).get('field').value;
if (fromValue && toValue && fromValue === toValue) {
console.log('Control: ', control);
return { 'fieldMatch' : true };
}
console.log('Control: ', control);
return null;
}
}

get group2Field() {
return (<FormGroup>this.mainForm.get('group2')).get('field');
}
}


Template:



<form [formGroup]="mainForm">
<div formGroupName="group1">
<label for="">Group 1 Field</label>
<input type="text" formControlName="field">
</div>
<hr>
<div formGroupName="group2">
<label for="">Group 2 Field</label>
<input type="text" formControlName="field">
<p *ngIf="group2Field?.errors?.fieldMatch">These fields match</p>
</div>
</form>


Here's a Sample StackBlitz for your ref.






share|improve this answer


























  • It's a good answer. But what if we have a dynamically creating groups? I mean what if we don't know how many groups will be? For example if I'll create a form via iterating of some array? I need a universal validator to validate all fields inside

    – hofshteyn
    Nov 22 '18 at 8:51








  • 1





    @hofshteyn, I think you're pivoting from the original question here. Please consider asking a different question with all the relevant details. Or you should have specified all the relevant details in the OP in the first place. I'm suggesting this as this way it won't create any additional noise on this thread. Just keeps the site clean and accurate. :)

    – SiddAjmera
    Nov 22 '18 at 8:54











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53426241%2fangular-form-validation-compare-two-fields-in-different-form-groups%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














matchValidator will be called by Angular and not by you. So it won't have the access to the Component's this.



So you will have to bind to it.



You can use the get method on a FormGroup to get the group1's field's value: (<FormGroup>this.mainForm.get('group1')).get('field').value



Give this a try:



Component Class:



import { Component } from '@angular/core';
import { FormGroup, FormBuilder, FormControl, ValidatorFn, AbstractControl } from '@angular/forms';

@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
mainForm: FormGroup;

constructor(private fb: FormBuilder) { }

ngOnInit() {
this.mainForm = this.fb.group({
group1: this.fb.group({
field:
}),
group2: this.fb.group({
field: [null, [this.matchValidator.bind(this)]]
})
});

}

matchValidator(control: AbstractControl): { [key: string]: boolean } | null {
const fromValue = control.value;
if(this.mainForm) {
const toValue = (<FormGroup>this.mainForm.get('group1')).get('field').value;
if (fromValue && toValue && fromValue === toValue) {
console.log('Control: ', control);
return { 'fieldMatch' : true };
}
console.log('Control: ', control);
return null;
}
}

get group2Field() {
return (<FormGroup>this.mainForm.get('group2')).get('field');
}
}


Template:



<form [formGroup]="mainForm">
<div formGroupName="group1">
<label for="">Group 1 Field</label>
<input type="text" formControlName="field">
</div>
<hr>
<div formGroupName="group2">
<label for="">Group 2 Field</label>
<input type="text" formControlName="field">
<p *ngIf="group2Field?.errors?.fieldMatch">These fields match</p>
</div>
</form>


Here's a Sample StackBlitz for your ref.






share|improve this answer


























  • It's a good answer. But what if we have a dynamically creating groups? I mean what if we don't know how many groups will be? For example if I'll create a form via iterating of some array? I need a universal validator to validate all fields inside

    – hofshteyn
    Nov 22 '18 at 8:51








  • 1





    @hofshteyn, I think you're pivoting from the original question here. Please consider asking a different question with all the relevant details. Or you should have specified all the relevant details in the OP in the first place. I'm suggesting this as this way it won't create any additional noise on this thread. Just keeps the site clean and accurate. :)

    – SiddAjmera
    Nov 22 '18 at 8:54
















1














matchValidator will be called by Angular and not by you. So it won't have the access to the Component's this.



So you will have to bind to it.



You can use the get method on a FormGroup to get the group1's field's value: (<FormGroup>this.mainForm.get('group1')).get('field').value



Give this a try:



Component Class:



import { Component } from '@angular/core';
import { FormGroup, FormBuilder, FormControl, ValidatorFn, AbstractControl } from '@angular/forms';

@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
mainForm: FormGroup;

constructor(private fb: FormBuilder) { }

ngOnInit() {
this.mainForm = this.fb.group({
group1: this.fb.group({
field:
}),
group2: this.fb.group({
field: [null, [this.matchValidator.bind(this)]]
})
});

}

matchValidator(control: AbstractControl): { [key: string]: boolean } | null {
const fromValue = control.value;
if(this.mainForm) {
const toValue = (<FormGroup>this.mainForm.get('group1')).get('field').value;
if (fromValue && toValue && fromValue === toValue) {
console.log('Control: ', control);
return { 'fieldMatch' : true };
}
console.log('Control: ', control);
return null;
}
}

get group2Field() {
return (<FormGroup>this.mainForm.get('group2')).get('field');
}
}


Template:



<form [formGroup]="mainForm">
<div formGroupName="group1">
<label for="">Group 1 Field</label>
<input type="text" formControlName="field">
</div>
<hr>
<div formGroupName="group2">
<label for="">Group 2 Field</label>
<input type="text" formControlName="field">
<p *ngIf="group2Field?.errors?.fieldMatch">These fields match</p>
</div>
</form>


Here's a Sample StackBlitz for your ref.






share|improve this answer


























  • It's a good answer. But what if we have a dynamically creating groups? I mean what if we don't know how many groups will be? For example if I'll create a form via iterating of some array? I need a universal validator to validate all fields inside

    – hofshteyn
    Nov 22 '18 at 8:51








  • 1





    @hofshteyn, I think you're pivoting from the original question here. Please consider asking a different question with all the relevant details. Or you should have specified all the relevant details in the OP in the first place. I'm suggesting this as this way it won't create any additional noise on this thread. Just keeps the site clean and accurate. :)

    – SiddAjmera
    Nov 22 '18 at 8:54














1












1








1







matchValidator will be called by Angular and not by you. So it won't have the access to the Component's this.



So you will have to bind to it.



You can use the get method on a FormGroup to get the group1's field's value: (<FormGroup>this.mainForm.get('group1')).get('field').value



Give this a try:



Component Class:



import { Component } from '@angular/core';
import { FormGroup, FormBuilder, FormControl, ValidatorFn, AbstractControl } from '@angular/forms';

@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
mainForm: FormGroup;

constructor(private fb: FormBuilder) { }

ngOnInit() {
this.mainForm = this.fb.group({
group1: this.fb.group({
field:
}),
group2: this.fb.group({
field: [null, [this.matchValidator.bind(this)]]
})
});

}

matchValidator(control: AbstractControl): { [key: string]: boolean } | null {
const fromValue = control.value;
if(this.mainForm) {
const toValue = (<FormGroup>this.mainForm.get('group1')).get('field').value;
if (fromValue && toValue && fromValue === toValue) {
console.log('Control: ', control);
return { 'fieldMatch' : true };
}
console.log('Control: ', control);
return null;
}
}

get group2Field() {
return (<FormGroup>this.mainForm.get('group2')).get('field');
}
}


Template:



<form [formGroup]="mainForm">
<div formGroupName="group1">
<label for="">Group 1 Field</label>
<input type="text" formControlName="field">
</div>
<hr>
<div formGroupName="group2">
<label for="">Group 2 Field</label>
<input type="text" formControlName="field">
<p *ngIf="group2Field?.errors?.fieldMatch">These fields match</p>
</div>
</form>


Here's a Sample StackBlitz for your ref.






share|improve this answer















matchValidator will be called by Angular and not by you. So it won't have the access to the Component's this.



So you will have to bind to it.



You can use the get method on a FormGroup to get the group1's field's value: (<FormGroup>this.mainForm.get('group1')).get('field').value



Give this a try:



Component Class:



import { Component } from '@angular/core';
import { FormGroup, FormBuilder, FormControl, ValidatorFn, AbstractControl } from '@angular/forms';

@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
mainForm: FormGroup;

constructor(private fb: FormBuilder) { }

ngOnInit() {
this.mainForm = this.fb.group({
group1: this.fb.group({
field:
}),
group2: this.fb.group({
field: [null, [this.matchValidator.bind(this)]]
})
});

}

matchValidator(control: AbstractControl): { [key: string]: boolean } | null {
const fromValue = control.value;
if(this.mainForm) {
const toValue = (<FormGroup>this.mainForm.get('group1')).get('field').value;
if (fromValue && toValue && fromValue === toValue) {
console.log('Control: ', control);
return { 'fieldMatch' : true };
}
console.log('Control: ', control);
return null;
}
}

get group2Field() {
return (<FormGroup>this.mainForm.get('group2')).get('field');
}
}


Template:



<form [formGroup]="mainForm">
<div formGroupName="group1">
<label for="">Group 1 Field</label>
<input type="text" formControlName="field">
</div>
<hr>
<div formGroupName="group2">
<label for="">Group 2 Field</label>
<input type="text" formControlName="field">
<p *ngIf="group2Field?.errors?.fieldMatch">These fields match</p>
</div>
</form>


Here's a Sample StackBlitz for your ref.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 22 '18 at 8:39

























answered Nov 22 '18 at 8:18









SiddAjmeraSiddAjmera

15.5k31238




15.5k31238













  • It's a good answer. But what if we have a dynamically creating groups? I mean what if we don't know how many groups will be? For example if I'll create a form via iterating of some array? I need a universal validator to validate all fields inside

    – hofshteyn
    Nov 22 '18 at 8:51








  • 1





    @hofshteyn, I think you're pivoting from the original question here. Please consider asking a different question with all the relevant details. Or you should have specified all the relevant details in the OP in the first place. I'm suggesting this as this way it won't create any additional noise on this thread. Just keeps the site clean and accurate. :)

    – SiddAjmera
    Nov 22 '18 at 8:54



















  • It's a good answer. But what if we have a dynamically creating groups? I mean what if we don't know how many groups will be? For example if I'll create a form via iterating of some array? I need a universal validator to validate all fields inside

    – hofshteyn
    Nov 22 '18 at 8:51








  • 1





    @hofshteyn, I think you're pivoting from the original question here. Please consider asking a different question with all the relevant details. Or you should have specified all the relevant details in the OP in the first place. I'm suggesting this as this way it won't create any additional noise on this thread. Just keeps the site clean and accurate. :)

    – SiddAjmera
    Nov 22 '18 at 8:54

















It's a good answer. But what if we have a dynamically creating groups? I mean what if we don't know how many groups will be? For example if I'll create a form via iterating of some array? I need a universal validator to validate all fields inside

– hofshteyn
Nov 22 '18 at 8:51







It's a good answer. But what if we have a dynamically creating groups? I mean what if we don't know how many groups will be? For example if I'll create a form via iterating of some array? I need a universal validator to validate all fields inside

– hofshteyn
Nov 22 '18 at 8:51






1




1





@hofshteyn, I think you're pivoting from the original question here. Please consider asking a different question with all the relevant details. Or you should have specified all the relevant details in the OP in the first place. I'm suggesting this as this way it won't create any additional noise on this thread. Just keeps the site clean and accurate. :)

– SiddAjmera
Nov 22 '18 at 8:54





@hofshteyn, I think you're pivoting from the original question here. Please consider asking a different question with all the relevant details. Or you should have specified all the relevant details in the OP in the first place. I'm suggesting this as this way it won't create any additional noise on this thread. Just keeps the site clean and accurate. :)

– SiddAjmera
Nov 22 '18 at 8:54




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53426241%2fangular-form-validation-compare-two-fields-in-different-form-groups%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

'app-layout' is not a known element: how to share Component with different Modules

android studio warns about leanback feature tag usage required on manifest while using Unity exported app?

WPF add header to Image with URL pettitions [duplicate]