I am working on billing of product page based on product list using Angular as front end.
Here when I selected product "apple" the price should be calculated and displayed in price control input. ie. price= product price * quantity e.g. 10*1=10 Below my component html code
<form [formGroup]="productFormarray" (ngSubmit)="onSubmit()">
<div class="reg-right">
<div class="formGroup">
<label for="customername" class="form-label">Customer Name</label>
<input type="text" class="form-control" id="customername" placeholder="Customer Name"
formControlName="customername">
</div>
<div class="formGroup" formArrayName="productdetails">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr> <td style="width:50%">
Product Name
</td>
<td style="width:15%">
Quantity
</td>
<td style="width:20%">
Price
</td></tr>
</thead>
<tr *ngFor="let product of productdetailsarray.controls; let i=index" [formGroupName]="i">
<td style="width:50%">
<div class="formGroup">
<select class="form-control" id="productname" formControlName="productname" name="productname" placeholder="Product Name">
<option disabled>select product</option>
<option *ngFor="let product of productlist" [ngValue]="product.productname">
{{product.productname}}
</option>
</select>
</div>
</td>
<td style="width:15%">
<div class="formGroup">
<select class="form-control" id="quantit" formControlName="quantit" name="quantit">
<option *ngFor="let quantity of quantitylist" [ngValue]="quantity">
{{quantity}}
</option>
</select>
</div>
</td>
<td style="width:20%">
<div class="formGroup">
<input type="text" class="form-control" id="price" formControlName="price" placeholder="Price "
name="price" [value]="'33'">
</div>
</td>
<td>
<a type="button" class="btn btn-primary btn-sm mt-4" style="background-color: red;"
(click)="removeProduct(i)">Remove (-)</a>
</td>
</tr>
</table>
</div>
<a type="button" class="btn btn-secondary" style="background-color: green;"
(click)="addNewProduct()">Add(+)</a>
<br/>
</div>
<div class="mb-4 mt-4 col-md-12">
<div class="formGroup">
<label class="form-check-label">
<input class="form-check-input" formControlName="remember" type="checkbox" name="remember"> Remember
me
</label>
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
Below my component typescript code
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormGroup, FormControl, FormArray, FormBuilder, NgForm, Validators } from '@angular/forms'
import { Observable, of } from 'rxjs';
import { toArray } from 'rxjs';
@Component({
selector: 'app-billing',
templateUrl: './billing.component.html',
styleUrls: ['./billing.component.css']
})
export class BillingComponent implements OnInit {
name = 'Bill';
productsForm!: NgForm;
@ViewChild('productsForm') productsForminput!: NgForm;
productFormarray: any;
quantitylist = [0.5, 1, 1.5];
items!: FormArray;
ind: number = 0;
i: number = 0;
productlist = [{ productname: "apple", price: 10 }, { productname: "orange", price: 10 }, { productname: "lemon", price: 30 }];
constructor(private fb: FormBuilder) {
this.productFormarray = new FormGroup({
customername: new FormControl('', Validators.required),
productdetails: new FormArray([]),
remember: new FormControl('true')
})
}
addNewProduct() {
this.items = this.productFormarray.get('productdetails') as FormArray;
this.items.push(this.createNewProduct());
this.productFormarray.get('productdetails').controls[this.ind].get('quantit').setValue(this.quantitylist[1]);
this.ind = this.ind + 1;
}
createNewProduct(): FormGroup {
return new FormGroup({
productname: new FormControl('', Validators.required),
quantit: new FormControl('1', Validators.required),
price: new FormControl('', Validators.required)
})
}
removeProduct(index: any) {
this.items = this.productFormarray.get('productdetails') as FormArray;
this.items.removeAt(index);
}
get productdetailsarray() {
return this.productFormarray.get('productdetails') as FormArray;
}
ngOnInit() {
this.addNewProduct();
}
onSubmit() {
}
}
Can someone please help me in getting the price value.
You can achieve this by getting product
and quintity
value and listen those into the addNewProduct
onProductChange(selectedProductName: string, index: number) {
const selectedProduct = this.productlist.find(
(product) => product.productname === selectedProductName
);
if (selectedProduct) {
const productDetailsArray = this.productFormarray.get(
'productdetails'
) as FormArray;
if (productDetailsArray && productDetailsArray.at(index)) {
const quantityControl = productDetailsArray.at(index).get('quantit');
if (quantityControl) {
// Reset the quantity to its default value
quantityControl.setValue(this.quantitylist[1], { emitEvent: false });
const quantity = quantityControl.value;
const price = selectedProduct.price * quantity;
const priceControl = productDetailsArray.at(index).get('price');
if (priceControl) {
priceControl.setValue(price);
}
}
}
}
}
onQuantityChange(selectedQuantity: number, index: number) {
const productDetailsArray = this.productFormarray.get(
'productdetails'
) as FormArray;
if (productDetailsArray && productDetailsArray.at(index)) {
const productNameControl = productDetailsArray
.at(index)
.get('productname');
if (productNameControl) {
const selectedProductName = productNameControl.value;
const selectedProduct = this.productlist.find(
(product) => product.productname === selectedProductName
);
if (selectedProduct) {
const price = selectedProduct.price * selectedQuantity;
const priceControl = productDetailsArray.at(index).get('price');
if (priceControl) {
priceControl.setValue(price);
}
}
}
}
}
addNewProduct() {
this.items = this.productFormarray.get('productdetails') as FormArray;
const newProduct = this.createNewProduct();
this.items.push(newProduct);
const index = this.items.length - 1;
newProduct.get('quantit')?.setValue(this.quantitylist[1]);
const productNameControl = newProduct.get('productname');
if (productNameControl) {
productNameControl.valueChanges.subscribe((selectedProductName) =>
this.onProductChange(selectedProductName, index)
);
}
const quantityControl = newProduct.get('quantit');
if (quantityControl) {
quantityControl.valueChanges.subscribe((selectedQuantity) =>
this.onQuantityChange(selectedQuantity, index)
);
}
}
Here is the working example [Stackblitz]