[ReferenceImage][1]
->Hello, I need to do the calculation for two fields look at the reference image once.
->In the basic pay field if I enter 100 and in Gst % on the first premium amount if I enter 5 then automatically in the first premium amount 105 value should display calculation is like (100 50 = 105).
->same if I enter 5 in GST % on next premium amount 105 should be displayed in the next premium amount field. [1]: https://i.stack.imgur.com/KNtAa.png
CodePudding user response:
if you are using angular reactive forms, you can use the patchValue() method of the FormGroup.
You can refer the document link: Angular document for reactive forms
In your case you can call the patchValue method onKeyPress.
CodePudding user response:
It's a problem very common to have a form with some "calculated value".
In Angular we has two aproach to mannage forms: Reactive Forms (the formGroup and FormControl) or Template driven form (the [(ngModel)])
If we use [(ngModel)] we can store the calculate value in a variable (or not). If we use FormGroup we can store the calculate value in a FormControl of the FormGroup or not. Really it's unnecessary store the value calculate. We can make, e.g.
<form #f="ngForm">
<input name="cant" [(ngModel)]="cant" />
<input name="porc" [(ngModel)]="porc" />
<input name="result" readonly [ngModel]="( cant * porc) / 100" />
</form>
{{f.value|json}} <---just to check
//in .ts
cant:number=0;
porc:number=0;
or
<form [formGroup]="form">
<input formControlName="cant">
<input formControlName="porc">
<input readonly [ngModel]=" form.value.cant*( form.value.porc)/100"
[ngModelOptions]="{standalone:true}">
</form>
{{form?.value|json}} <--just to check
//in .ts
form=new FormGroup({
cant:new FormControl(0),
porc:new FormControl(0)
})
See that always need convert to number the "values". It's the reason to add the to the values. See also that the only code in .ts is declare the variables or declare the formGroup
I use a input readonly, but you can use a span or a div
Well, if we want to store the result in a variable -or in a FormControl of the formGroup we need make some changes
<form #f="ngForm">
<input name="cant" [ngModel]="cant"
(ngModelChange)="cant= $event;calculateResult()" />
<input name="porc" [(ngModel)]="porc"
(ngModelChange)="porc= $event;calculateResult()"/>
<input name="result" readonly [ngModel]="result" />
</form>
{{f.value|json}}
//in .ts
//add a new variable
result:number=0
//and add the function calculateResult
calculateResult(){
this.result=this.cant*this.porc/100
}
See how "split" the [(ngModel)] in [ngModel] and (ngModelChange).
Using reactive form
<form [formGroup]="form">
<input formControlName="cant" (input)="calculateResultForm()" />
<input formControlName="porc" (input)="calculateResultForm()"/>
<input readonly formControlName="result" />
/>
</form>
//in .ts
form=new FormGroup({
cant:new FormControl(0),
porc:new FormControl(0),
result:new FormControl(0) //<--we add this FormControl
})
//and the function
calculateResultForm()
{
this.form.get('result').setValue(
this.form.value.cant*( this.form.value.porc)/100)
}
Well, in reactiveForms is common use the observable valueChanges instead of using the event input. valueChanges are an observable. This mean that you can subscribe to changes (in ngOnInit). e.g. we can do
ngOnInit(){
this.form.get('cant').valueChanges.subscribe((res:any)=>{
this.calculateResultForm()
})
this.form.get('porc').valueChanges.subscribe((res:any)=>{
this.calculateResultForm()
})
}
calculateResultForm()
{
//see that in this case we can NOT use
//this.form.value.cant and this.form.value.porc
//because the value is with the old values
const cant= this.form.get('cant').value
const porc= this.form.get('porc').value
this.form.get('result').setValue(cant*porc/100)
}
Well the "problem" with the observables is that we need unsubscribe in ngDestroy of the component, so we declare two variables
sub1:Subscription
sub2:Subcription
When use the valueChanges we use
this.sub1=this.form.get('cant').valueChanges.subscribe((res:any)=>{
this.calculateResultForm()
})
this.sub2=this.form.get('porc').valueChanges.subscribe((res:any)=>{
this.calculateResultForm()
})
And in ngOnDestroy we write
ngOnDestroy(){
this.sub1.unsubscribe()
this.sub2.unsubscribe()
}
Well really nobody subscribe each FormControl, generally we use an rxjs operator to create an unique subcription.
We can use rxjs operator merge
. don't worry it's only put the values changes separated by commas
this.sub1=merge(
this.form.get('cant').valueChanges,
this.form.get('porc').valueChanges
).subscribe((res:any)=>{
this.calculateResultForm()
})
Others ways are use forkJoin or similar, use takeUntil or takeWhile to unsubscribe automatically, etc. but this answer is yet a bit large
NOTE: I know that the first time you meet ReactiveForms and Observables scare a few. Really they are a powerful tool and we need understand a bit about they
If you get the final of the answer, great!, you can check the stackblitz