Sergio Cano
Sergio Cano

Reputation: 760

Reactive forms and math operations with different inputs in Angular 5

I'm trying to develop something really silly, but I am little bit stuck with it.

I have 3 inputs. In the first input, the customer introduces a price; in the second input, the customer chooses an option; and in the third input, load the result.

I'm trying to do it with reactive forms with Angular 5, and I can't set the value on the third input correctly. I let you code here.

<div class="form-row">
  <div class="form-group col-md-5">
    <label>Purchase price</label>
    <input type="text" class="form-control" formControlName="purchaseprice">
  </div>
  <div class="form-group col-md-2">
    <label>Taxes</label>
    <select class="form-control" formControlName="taxes">
      <option>21%</option>
      <option>10%</option>
      <option>4%</option>
    </select>
  </div>
  <div class="form-group col-md-5">
    <label>Purchase price + Taxes.</label>
    <input type="text" class="form-control" 
           formControlName="pricetaxes">
  </div>
</div>

Upvotes: 1

Views: 3675

Answers (4)

Sergio Cano
Sergio Cano

Reputation: 760

After check the posts that you guys did. i had enough info to solve my problem.

Here i let you with 3 inputs, how the customer can check both prices and calculate it with different taxes.

You can check the Stackblitz demo ->> https://stackblitz.com/edit/angular-atbmpa

Upvotes: 2

maxime1992
maxime1992

Reputation: 23803

TS:

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  public form: FormGroup = new FormGroup({
    purchasePrice: new FormControl(''),
    taxes: new FormControl(''),
  });

  get purchasePrice(): number {
    return +this.form.get('purchasePrice').value;
  }

  get taxes(): number {
    return +this.form.get('taxes').value / 100;
  }

  get totalPrice(): number {
    return this.purchasePrice + (this.purchasePrice * this.taxes);
  }
}

HTML:

<form [formGroup]="form">
  <div>
    <label>Purchase price</label>
    <input type="number" formControlName="purchasePrice">
  </div>

  <div>
    <label>Taxes</label>
    <select formControlName="taxes">
      <option [value]="21">21%</option>
      <option [value]="10">10%</option>
      <option [value]="4">4%</option>
    </select>
  </div>

  <div>
    <span [ngClass]="{ 'valid': purchasePrice, 'invalid': !purchasePrice }">Purchase price</span>
    +
    <span [ngClass]="{ 'valid': taxes, 'invalid': !taxes }">Taxes</span>: 

    <ng-container *ngIf="purchasePrice && taxes; else fillTheForm">
      <b>{{ totalPrice }}</b>
    </ng-container>

    <ng-template #fillTheForm>
      Please fill the form
    </ng-template>
  </div>
</form>

Here's a Stackblitz demo https://stackblitz.com/edit/angular-ohmdj2

Of course you can easily add a submit method like that (added on Stackblitz)

  submit() {
    const finalRes = {
      purchasePrice: this.purchasePrice,
      taxes: this.taxes,
      totalPrice: this.totalPrice
    };

    console.log(finalRes)
  }

Upvotes: 0

Eliseo
Eliseo

Reputation: 57939

With Reactive Form, you think that the data of the form are percent and price. The total is not a data. So

<form [formGroup]="myForm" (submit)=submit(myForm)>
  <select class="form-control" name="taxes" formControlName="percent" >
    <option [value]="0">No Discount</option>
    <option [value]="21">21%</option>
       <option [value]="10">10%</option>
       <option [value]="4">4%</option>
  </select>
  <input formControlName="price">
  <!--see that the "total" is NOT a formGroupName. Is a simple input with [value] -->
  <input [value]="(100-myForm.get('percent').value)*myForm.get('price').value/100.0">
  <button>submit</button>
</form>
{{myForm?.value |json}}

See how we create the data in a submit

constructor(private fb:FormBuilder){

ngOnInit()
  {
    //See that my form only have "percent" and "price"
    this.myForm=this.fb.group({
      percent:0,
      price:0
    })
  }
  //In the submit function
  submit(myForm:FormGroup)
  {
    if (myForm.valid)
    {
      //we create a object data with all the properties of myForm
      //we're using the spread operator the theee points
      // and the property "total"
      var data={...myForm.value,
                total:(100-myForm.value.percent)*myForm.value.price/100.0};
      console.log(data);
    }
  }

Upvotes: 2

Akhil Aravind
Akhil Aravind

Reputation: 6130

I have implemented the solution in this way, this is the component.html

<form #form="ngForm">
<div class="form-row">
    <div class="form-group col-md-5">
        <label>Purchase price</label>
        <input type="text" class="form-control" name="purchaseForm" [(ngModel)]="model.pprice">
    </div>
    <div class="form-group col-md-2">
        <label>Taxes</label>
        <select class="form-control" name="taxes" (change)="calculate()"  [(ngModel)]="model.tax">
            <option value="21">21%</option>
            <option value="10">10%</option>
            <option value="4">4%</option>
        </select>
    </div>
    <div class="form-group col-md-5">
        <label>Purchase price + Taxes.</label>
        <input type="text" class="form-control" name="ptax" [(ngModel)]="model.total"> 
    </div>
</div>
</form>

The change event in the select box will trigger the function to calculate the total, this is the component.ts

model = {
    pprice:null,
    tax:null,
    total:null
  }

  calculate(){
    this.model.total = +this.model.pprice + +this.model.tax;
  }

This is the sample created

Code snippet

Upvotes: 0

Related Questions