0

I've dynamic reactive form. the problem I'm currently facing is that I want the price and loanTerm to be pre-selected when the product is selected. I know in regular forms it's just two-way data binding, but How do I do this in dynamic form.

here is my component code

 this.loanProductForm = this._formBuilder.group({
      products: this._formBuilder.array([
        this.addProductFormGroup()
      ])
    });

 addProductFormGroup(): FormGroup {
    return this._formBuilder.group({
      productId: ['', Validators.required],
      price: [0, Validators.required],
      loanTermId: ['', Validators.required],
      quantity: [0, Validators.required],
      deposit: [0, Validators.required],
      total: [0, Validators.required],
    });
  }

addProductButtonClick(): void {
    (<FormArray>this.loanProductForm.get('products')).push(this.addProductFormGroup());
    console.log('Loan Products: ', this.loanProductForm.value)
  }

and here is html code

<form [formGroup]="loanProductForm">
    <table style="overflow-x: auto;display: inline-block; white-space: nowrap;">
        <thead>
            <tr class='tableHeader'>
                <div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
                    <td fxFlex="22" class="pr-4">Name</td>
                    <td fxFlex="15" class="pr-4">Price</td>
                    <td fxFlex="15" class="pr-4">Loan Term</td>
                    <td fxFlex="15" class="pr-4">Quantity</td>
                    <td fxFlex="15" class="pr-4">Deposit</td>
                    <td fxFlex="15" class="pr-4">Total</td>
                </div>
            </tr>
        </thead>
        <tbody>
            <tr formArrayName="products" *ngFor="let product of loanProductForm.get('products').controls; let i = index">
                <div [formGroupName]="i" fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
                    <td fxFlex="22">
                        <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                            <mat-label>Product </mat-label>
                            <mat-select formControlName="productId" [id]="'productId' + i" required>
                                <mat-option *ngFor="let product of productList" [value]="product.productId">
                                    {{product.name}}
                                </mat-option>
                            </mat-select>

                        </mat-form-field>
                    </td>
                    <td fxFlex="15">
                        <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                            <mat-label>Price </mat-label>
                            <input type='number' (keyup)="onPriceChange($event)" matInput formControlName="price" [id]="'price' + i" name="" placeholder="Price" required>
                        </mat-form-field>
                    </td>
                    <td fxFlex="15">
                        <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                            <mat-label>Loan Term </mat-label>
                            <mat-select formControlName="loanTermId" [id]="'loanTermId' + i" required>
                                <mat-option *ngFor="let loanTerm of loanTermList" [value]="loanTerm.loanTermId">
                                    {{loanTerm.numberOfMonths}}
                                </mat-option>
                            </mat-select>
                        </mat-form-field>
                    </td>
                    <td fxFlex="15">
                        <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                            <mat-label>Quantity </mat-label>
                            <input type='number' formControlName="quantity" [id]="'quantity' + i" matInput name="" id="" placeholder="Quantity" required>

                        </mat-form-field>
                    </td>
                    <td fxFlex="15">
                        <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                            <mat-label>Deposit </mat-label>
                            <input type='number' formControlName="deposit" [id]="'deposit' + i" matInput name="" id="" placeholder="Deposit" required>
                        </mat-form-field>
                    </td>
                    <td fxFlex="15">
                        <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
                            <mat-label>Total </mat-label>
                            <input disabled type='number' formControlName="total" [id]="'total' + i" matInput name="total" id="" placeholder="Total" style="color:black; font-weight:bold" required>
                            <!-- <input disabled type='number' [(ngModel)]="totalValue" ngModel [ngModelOptions]="{standalone: true}" [id]="'total' + i" matInput name="total" id="" placeholder="Total" style="color:black; font-weight:bold" required> -->
                        </mat-form-field>
                    </td>

                </div>
            </tr>
            <tr>
                <td fxFlex="10">
                    <div fxLayout="row" fxLayoutAlign="start center" fxFlex="1 0 auto">
                        <button type="button" mat-stroked-button class='addBtn btn-style-2' fxFlex='100' (click)='addProductButtonClick()'>Add
                            <mat-icon matSuffix>add_box</mat-icon>
                        </button>
                    </div>
                </td>
            </tr>
        </tbody>
    </table>
</form>

price and loanTerm are the properties of product object. And I want them to be automatically selected as soon as I select the product from dropdown menu.

pictures for better understanding

enter image description here

1
  • Dynamic forms are regular forms. There's nothing different about them. If you want an option of a dropdown to be selected, then you should set the value of the form control bound to the dropdown to the value of the option. Commented Dec 15, 2019 at 15:35

1 Answer 1

1

you ned to listen output event of matSelect and patch product value in your form something like this

<td fxFlex="22">
    <mat-form-field appearance="outline" fxFlex="100" class="pr-4">
        <mat-label>Product </mat-label>
        <mat-select (selectionChange)="onChangedProduct($event, i)" formControlName="productId" [id]="'productId' + i" required>
            <mat-option *ngFor="let product of productList" [value]="product.productId">
               {{product.name}}
            </mat-option>
        </mat-select>
     </mat-form-field>
</td>

and In your .ts

onChangedProduct(event, index) {
   const product = 
      this.productList.find(product => product.productId === event.value)
    if(product) {
       this.loanProductForm.get(['products', index + '', 'price']).patchValue(product.price);
       const loanTermId = null; // you need to find the loanTermId from loanTermList
        this.loanProductForm.get(['products', index + '', 'loanTermId']).patchValue(loanTermId)
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

price is not working, product object have recommended price which I want to be automatically filled once I select the product
@Lint you can replace the product.price to the product.(the key of recomended price )
No, the variable name for price is product.price you wrote correctly, but what I meant was that it was not working
I'm sorry but its working perfectly, Sorry I was making a mistake. Thank you so much for this. Thanks again

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.