I am trying to bind multiple input fields together but am having trouble doing so. I basically have multiple input fields where if one input field changes then the others should calculate and reflect values too. It is a length unit converter. Here is an example of what I am attempting that can be found on w3schools:
Here is my code:
HTML
Kilometer<mat-form-field appearance="outline">
<mat-label> Meter </mat-label>
<input matInput [(ngModel)]="meters" (change)="calculate()" type="number" />
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label> Centimeter </mat-label>
<input matInput [(ngModel)]="centimeters" (change)="calculate()" type="number" />
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label> Yard </mat-label>
<input matInput [(ngModel)]="yards" (change)="calculate()" type="number" />
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label> Miles </mat-label>
<input matInput [(ngModel)]="miles" (change)="calculate()" type="number" />
</mat-form-field>
<mat-form-field appearance="outline">
<mat-label> Inches </mat-label>
<input matInput [(ngModel)]="inches" (change)="calculate()" type="number" />
</mat-form-field>
TS
public kilometers = 0;
public meters = 0;
public centimeters = 0;
public yards = 0;
public inches = 0;
public miles = 0;
calculate() {
this.kilometers = this.kilometers;
this.kilometers = this.meters * 1000;
this.kilometers = this.centimeters * 100000;
this.kilometers = this.yards * 1094;
this.kilometers = this.inches * 39370;
this.kilometers = this.miles / 1,609;
}
Note: I can't use any libraries to do the calculations so I have created individual methods for each calculation eg. kilometer to meter etc(just done the kilometer conversions for now until I can get the logic working).
I have created a stackblitz example her: https://stackblitz.com/edit/angular-9-material-starter-f1drwx?file=src/app/app.component.html
CodePudding user response:
When a user enters a value, you need to adjust all other values to match. You need to know which one the user changed, otherwise you won't know the value to use to determine all other values.
So for each field, you add a handler - note I am using the (input)
event rather than change
, as input
will update as you type.
centimeterChanged(){
this.kilometers = this.centimeters * 100000;
this.meters = this.centimeters * 1000;
// set all others EXCEPT this.centimeters
}
Template:
<mat-form-field appearance="outline">
<mat-label> Centimeter </mat-label>
<input
matInput
[(ngModel)]="centimeters"
(input)="centimeterChanged()"
type="number"
/>
</mat-form-field>
Updated stackblitz: https://stackblitz.com/edit/angular-9-material-starter-kbp3ni?file=src/app/app.component.ts
CodePudding user response:
You can have different methods for each input field change. Let us take your example of calculating from kilometer. The method should be
calculateFromKilometer() {
this.meters = this.kilometers * 1000;
this.centimeters = this.kilometers * 100000;
// do other conversion from kilometers
}
You should call this from (change) event of kilometer textbox
You can do the same for meter textbox and method as follows
calculateFromMeter() {
this.kilometers = this.meters * 0.001;
this.centimeters = this.meters * 100;
// do other conversion from meters
}