Reputation: 21
I'm trying to give user the ability to update the quantity of their selection before product checkout. The code below allows only 1 character in the textbox. What changes can I make to allow user enter up to 2 characters?
https://stackblitz.com/edit/angular-kfiqrb?file=src%2Fapp%2Ftable-basic-example.html This solution works but the column is a div not a textbox
export class ProductSelection {
id!: number;
name!: string;
itemPrice!: number;
quantity!: number;
totalPrice!: number;
}
html file
<table>
<thead>
<tr>
<th>Name</th>
<th>ItemPrice</th>
<th>Quantity</th>
<th>Total</th>
</tr>
</thead>
<tbody *ngFor="let p of products; let i = index">
<tr>
<td>{{ p.name }}</td>
<td>{{ p.itemPrice }}</td>
<td>
<input type="text" value="{{ p.quantity }}" (input)="quantitychange($event, i)" />
</td>
<td>{{ p.totalPrice }}/td></td>
</tr>
</tbody>
</table>
<div>
<input type="button" (click)="checkout()" value="submit" />
</div>
ts file
products: ProductSelection[] = [];
constructor() {
this.products= [
{ id = 1, name = "name1", itemPrice: 3, quantity: 3, totalPrice: 9 },
{ id = 1, name = "name2", itemPrice: 1, quantity: 10, totalPrice: 10 },
{ id = 1, name = "name3", itemPrice: 4, quantity: 4, totalPrice: 16 }
]
}
quantitychange(event: any, row: number) {
let item = this.products[row];
item.totalPrice = (item.itemPrice * Number(event.data));
item.quantity = event.data;
this.products[row] = item;
}
checkout() {
let total = 0;
this.products.foreach(i => total += i.totalPrice);
//send to service
}
I get event data as undefined when I use (focusout) event.
PS: Sorry, I can't access github from my machine else I'd have created the stackblitz for this one. Are there any other alternatives?
Upvotes: 0
Views: 101
Reputation: 1
<table>
<thead>
<tr>
<th>Name</th>
<th>ItemPrice</th>
<th>Quantity</th>
<th>Total</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let p of products; let i = index">
<td>{{ p.name }}</td>
<td>{{ p.itemPrice }}</td>
<td>
<input type="number" [value]="p.quantity" (input)="quantitychange($event, i)" />
</td>
<td>{{ p.totalPrice }}</td>
</tr>
</tbody>
</table>
<div>
<input type="button" (click)="checkout()" value="submit" />
</div>
Here, the changes i have made are:
Moved *ngFor="let p of products; let i = index"
from the <tbody>
tag to the <tr>
tag, because it is to be repeated for all new rows added in the table.
[value]="p.quantity"
, this way ensures that when the value changes the quantity will be updated.
Found a syntax error <td>{{ p.totalPrice }}/td></td>
which is to be <td>{{ p.totalPrice }}</td>
Moreover, u can change the input type to number ensuring only numbers are entered.
<input type="number" [value]="p.quantity" (input)="quantitychange($event, i)" />
Upvotes: 0
Reputation: 56052
You can just use Template Driven Forms
for this, [(ngModel)]
will two way bind the values to the data object so that when you update in code it will reflect in UI and when you type in HTML it will update the data. You can use (ngModelChange)
to trigger the calculation whenever the input changes, I also changed the input to accept only number values!
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
export class ProductSelection {
id!: number;
name!: string;
itemPrice!: number;
quantity!: number;
totalPrice!: number;
}
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, FormsModule],
template: `
<table>
<thead>
<tr>
<th>Name</th>
<th>ItemPrice</th>
<th>Quantity</th>
<th>Total</th>
</tr>
</thead>
<tbody *ngFor="let p of products; let i = index">
<tr>
<td>{{ p.name }}</td>
<td>{{ p.itemPrice }}</td>
<td>
<input type="number" [(ngModel)]="p.quantity" (ngModelChange)="quantitychange($event, i)" />
</td>
<td>{{ p.totalPrice }}</td>
</tr>
</tbody>
</table>
<div>
<input type="button" (click)="checkout()" value="submit" />
</div>
`,
})
export class App {
products: ProductSelection[] = [];
constructor() {
this.products = [
{ id: 1, name: 'name1', itemPrice: 3, quantity: 3, totalPrice: 9 },
{ id: 1, name: 'name2', itemPrice: 1, quantity: 10, totalPrice: 10 },
{ id: 1, name: 'name3', itemPrice: 4, quantity: 4, totalPrice: 16 },
];
}
quantitychange(event: any, row: number) {
let item = this.products[row];
item.totalPrice = item.itemPrice * Number(event);
item.quantity = event.data;
this.products[row] = item;
}
checkout() {
let total = 0;
this.products.forEach((i) => (total += i.totalPrice));
alert(`Total Checkout quantity: ${total}`);
//send to service
}
}
bootstrapApplication(App);
Upvotes: 0