Link to home
Start Free TrialLog in
Avatar of Zolf
ZolfFlag for United Arab Emirates

asked on

Angular Reactive form - Check user entered quantity

Hi there,

I have a form and I want to validate that the user does not enter quantity more then the quantity returned from the server response. Use case is as follows:
User selects a name from a drop down and the app takes the id and retrieve the related data for the selected name. One of the retrieved parameter is quantity. Now I want to make sure the user does not enter in the input component more then the quantity retrieved from the server. How can I implement this feature.

My HTML component looks like so,
 <div formArrayName="rawmaterialwh">
                <div [formGroupName]="i" *ngFor="let product of products.controls; let i=index">
                   <legend>{{i+1}}</legend>           
                      <div fxLayout="row wrap" fxLayoutAlign="space-between center">
                         <mat-form-field  attr.for="{{'rawmaterialid' + i}}">
                           <mat-label>{{'Raw Material'|translate}}</mat-label>
                            <mat-select formControlName="rawmaterialid" (selectionChange)="onProductValueChange($event,i)">
                               <mat-option disabled selected hidden>{{'Raw Material'|translate}}</mat-option>
                               <mat-option *ngFor="let product_mode of productOption"
                                  [value]="product_mode.rawmaterialid">{{product_mode.name}}</mat-option>
                            </mat-select>
                            <mat-error *ngIf="products.controls[i].get('rawmaterialid').hasError('required')"> {{'Select Raw Material'|translate}} </mat-error>
                         </mat-form-field>
                         <div fxFlex.gt-sm="49" fxFlex.gt-xs="49" fxFlex="100">
                            <mat-form-field class="full-wid mrgn-b-md">
                              <mat-label>{{'Quantity'|translate}}</mat-label>
                               <input matInput formControlName="qty">
                               <mat-error *ngIf="products.controls[i].get('qty').hasError('required')"> {{'You must include a quantity.'|translate}} </mat-error>
                            </mat-form-field>
                         </div>
                         <button *ngIf="!_isUpdating" class="mrgn-all-xs" class="mrgn-all-xs" mat-mini-fab color="warn"
                            (click)="deleteProduct(i)">
                            <mat-icon>delete</mat-icon>
                         </button>
                      </div>
                </div>
             </div>


Open in new window


And my server response I get is like so
Server response getRawMaterialQty()  [{"supplierid":39,"rawmaterialid":41,"rawmaterial_name":"Raw material 1","supplier_name":"Supplier 111","quantity":269}]

Open in new window


Avatar of Zolf
Zolf
Flag of United Arab Emirates image

ASKER

I am trying something on this basis.

I added a method to my input element in my html file

<div fxFlex.gt-sm="49" fxFlex.gt-xs="49" fxFlex="100">
                            <mat-form-field class="full-wid mrgn-b-md">
                              <mat-label>{{'Quantity'|translate}}</mat-label>
                               <input matInput formControlName="qty" (input)="validateQty($event.target.value)">
                               <mat-error *ngIf="products.controls[i].get('qty').hasError('required')"> {{'You must include a quantity.'|translate}} </mat-error>
                            </mat-form-field>
                         </div>



Open in new window


Then in my component class I define that method

validateQty(enteredQty: number): void {  
   
    console.log('QTY Entered',enteredQty);


    /* setTimeout(() => {
      console.log('setTimeout');
    if(enteredQty)
      console.log(this.products.get([index, "qty"]));
    }, 5 * 1000); */

  }

Open in new window

Now my problem is how to get the actual qty
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Zolf

ASKER

Thanks for your comment.

Give it a go and post back if you get stuck. 
I will go with option 1, hope to manage it!!
Note: setValidators will wipe out all previous validators on the control. So if your qty control has other validators on it you will have to add those to the array in the setValidators call.
Avatar of Zolf

ASKER

My form looks like so

this.form = this.fb.group({
      entrydate: ['',Validators.required],
      receiptno: ['',Validators.required],
      contractmfg: ['',Validators.required],
      rawmaterialwh: this.fb.array([this.buildProduct()],[Validators.required])
    });

Open in new window

buildProduct(): FormGroup {
      return this.fb.group({
        supplier: [''],
        rawmaterialid: ['',Validators.required],
        qty: ['', Validators.required],
      });
    }

Open in new window

And I want to have this validation on the qty. Do I need to add that validation to this buildProduct method also or not needed, I just added it dynamically in the onProductValueChange(data,index){ }

I am not sure I follow your logic here?
line 13 - what are you doing there ? You are setting element to the current rawmaterial item but then do nothing with element.

What is displaySupplierMultipleRawMaterial doing - and why is it an observable - what is it doing internally.

Why are you setting the validator only if the length of the returned rawmaterial value is 1?

Can you fill in some of the gaps.

Avatar of Zolf

ASKER

Thanks for your easy and professional suggestion!!
I am not sure I follow your logic here?line 13 
are you referring to this issue or my previous post?

What is displaySupplierMultipleRawMaterial doing - and why is it an observable - what is it doing internally. 
you see, when the user selects a raw material from the select element, I take the id of the raw material and get its respective data from the server. Now I have two case, either the raw material belongs to one supplier or multiple suppliers can have the same raw material, hence that check to see the raw material selected has one supplier or multiple suppliers. if it has multiple supplier, the app opens a dialog showing the user which supplier's raw material it wants to use.

Why are you setting the validator only if the length of the returned rawmaterial value is 1?
Just to get started first and good feeling I used the case where the rawmaterial.length(meaning the raw material selected has one supplier) is one.
Now that it is working for this case, I will go ahead and implement for the if case, where I open a dialog and the user has to enter the quantity there.

 displaySupplierMultipleRawMaterial(data){
    console.log('data!!',data); 

   console.log('data!!',data); 
   let dialogRef : MatDialogRef<SupplierMultipleRawMaterialDialog>;
   dialogRef = this.dialog.open(SupplierMultipleRawMaterialDialog);
   dialogRef.componentInstance.data = data;

   return dialogRef.afterClosed();
  }



Open in new window

Avatar of Zolf

ASKER

Julian
You can refer to this question for a video of my form, to give you idea how it works

https://www.experts-exchange.com/questions/29204559/Angular-Form-validation-issue-for-Array-form-section.html#questionAdd
I understand - thank you for the clarification.