1

I want to hook up 2 input controls to each other, so when one changes, it updates the other. As an example, its 2 percentage fields, if I set one to 80, the other will get set to 20 to balance it to total 100.

Both inputs are in a form group, so I feel like I should use these and methods on these to subscribe to value changes and not touch native elements or events.

Can anyone suggest the base way to go about it?

Michael Baldry
  • 1,990
  • 2
  • 14
  • 28

3 Answers3

2

You can subscribe to valueChanges for that particular formControlName. For example in your controller you can do

this.myForm.get('firstControl').valueChanges.subscribe(val => {
    this.myForm.patchValue({
       secondControl:100-val
    });
});

You should repeat the same to listen when the second control changes. Remember to validate with max values too i.e set maximum to 100.

1

A simple way would be to use the ngModelChange event emitted by one input field to update the other.

In the code below it updates input #2 when input #1 changes, and vice versa.

Input 1: <input type="text" [(ngModel)]="first" (ngModelChange)="second = 100 - first" />

Input 2: <input type="text" [(ngModel)]=second (ngModelChange)="first = 100 - second"/>

Note: this is pretty basic, all inline, but in your example you'd want to add some error handling for non-numeric characters, range values > 100 etc. So you might want to define the handler for ngModelChange in your components definition (presumably in typescript) rather than in the template like I've done here.

Garth Mason
  • 7,611
  • 3
  • 30
  • 39
  • I didn't want to have to attach events to things, I just wanted to point to them by another component. – Michael Baldry Sep 21 '17 at 14:59
  • Because your components are side-by-side you have a need of events, angular adheres to a [unidirectional data flow](https://stackoverflow.com/questions/39708018/angular2-unidirectional-data-flow) approach which is binding+events – Brandon Culley Sep 21 '17 at 15:41
-1

I'm using angular reactive forms and was able to create a component that binds to the form FormGroup and the names of the controls, like this:

<app-percentage-balance
    [formGroup]="form"
    firstControlName="firstControl"
    secondControlName="firstControl">

in my component I have:

@Input() formGroup: FormGroup;
@Input() firstControlName: string;
@Input() secondControlName: string;

public ngOnInit(): void {
    this.firstControl = this.formGroup.controls[this.firstControlName] as FormControl;
    this.secondControl = this.formGroup.controls[this.secondControlName] as FormControl;

    this.firstControl.statusChanges.subscribe((status) => {
      if (status == "VALID") {
        // do stuff
      }
    });

    this.secondControl.statusChanges.subscribe((status) => {
      if (status == "VALID") {
        // do stuff
      }
    });
}
Michael Baldry
  • 1,990
  • 2
  • 14
  • 28