1
votes

Please refer to complete code here at stackblitz

When modify the first columnm dropdown to Model, it's observed that the 3rd column show list of models.

click on add row button --> for second row, modify the first column dropdown to System --> observed that the third column dropdown for the second row changed to system list too. However, it also modifies the third col of the other rows too . is there a way that I can modify only the third column of the second row ?

So the formControlName is the same in the ngFor loop, and I would like to watch the changes in the formControl and update the third column dropdown values only for that row (not all rows)

At stackblitz

  • do you know why when choose 'contains' option in the second column, the third column is showing Object object. Would prefer a blank input value.

  • do you also know how to show the default value for the input box, i.e. would like to show the first item from every dropdown list when the page first load / when add a new row.

    <form class="form" [formGroup]="form" noValidate>
      <div *ngFor="let row of rows" class="rows">
       <div>
            <select  formControlName="getType">
               <option *ngFor="let val of rootName"
                            [value]="val">
                        {{ val }}
                </option>
             </select>
        </div>
        <div>
             <select formControlName="typeValues">
               <option *ngFor="let val of type"
                  [value]="val">
                  {{ val }}
               </option>
             </select>
         </div>
         <div *ngIf="getValues.length>0" >
             <select formControlName="onValues">
                <option *ngFor="let val of getValues"
                        [value]="val">
                        {{ val }}
                </option>
              </select>
         </div>
         <div class="row-button">
             <button (click)="addRow()" [title]="'Add row'"> 
             </button>
         </div>
    
     rows = [0];
     this.form
        .get('typeValues')
        .valueChanges.pipe(takeUntil(this.ngUnsubscribe))
        .subscribe(val => {
            this.setValues();
        });
    
      this.form
          .get('getType')
          .valueChanges.pipe(takeUntil(this.ngUnsubscribe))
          .subscribe(val => {
              this.setValues();
          });
       }
    
     setValues() {
        const name = this.form.controls['getType'].value;
        const type = this.form.controls['tpeValues'].value;
        if (name != null && (type === 'is' || type === 'is not')) {
           if (name === 'Model') {
              this.getValues = this.getModelList;
           } else if (name === 'System'){
              this.getValues = this.getSystemList;
           }else if (name === 'OS'){
              this.getValues = this.getOSList;
           }
        } else {
           this.getValues = [];
        }
    }
    
    addRow() {
       this.formDirty = true;
       this.rows.push(this.rows.length);
    }
    

    '

1
It doesn't look like you added enough code to recreate the problem. Could you add all relevant code, and preferably also create a stackblitz to demonstrate the problem.Kurt Hamilton
Hi Kurt, I've created a stackblitz. stackblitz.com/edit/angular-qqeywq When user click on add row and modify the first columnm dropdown to Model, it's observed that the 3rd column show list of models. When proceed to add row --> for second row --> modify the first column dropdown to System, --> the issue is that the third column dropdown for the first row/other row was changed to System list as well instead of showing model listuser21

1 Answers

1
votes

You need use a FormArray. I suppose you want do some like

formArray:FormArray=new FormArray([this.newLine()]);

newLine() //This funcrion is WORNG, see update 2
{
   return this.formBuilder.group({
     onValues: [
        { value: "" },
        [Validators.required, Validators.pattern(/^[+-]?\d+(\.\d+)?$/)]
      ],
      ruleTypeValues: [{ value: "" }],
      getType: [{ value: "" }], 
      filterValue: [{ value: "" }]
   })
}
addLine()
{
   this.formArray.push(this.newLine())
}
removeLine(index)
{
   this.formArray.removeAt(index)
}

To manage, take the look over formArray.controls using [formGroup]

<form class="form" [formGroup]="formArray">
      <div *ngFor="let group of formArray.controls;let i=index" [formGroup]="group" class="rows">
        <div class="clr-select-wrapper">
          <select formControlName="getType">
            <ng-container *ngFor="let val of rootName">
              <option [ngValue]="val">{{ val }}</option>
            </ng-container>
          </select>
        </div>
        <div class="clr-select-wrapper">
          <select formControlName="ruleTypeValues">
            <ng-container *ngFor="let val of ruleType">
              <option [ngValue]="val">{{ val }}</option>
            </ng-container>
          </select>
        </div>
        <div class="clr-select-wrapper" *ngIf="getValues.length > 0">
          <select formControlName="onValues">
            <ng-container *ngFor="let val of getValues">
              <option [ngValue]="val">{{ val }}</option>
            </ng-container>
          </select>
        </div>
        <input
          *ngIf="getValues.length === 0"
          type="text"
          formControlName="filterValue"
          class="text"
          placeholder="sdf"
        />
        <div class="row-button">
          <button  (click)="addLine()">Add row</button>
          <button  (click)="removeLine(i)">Remove row </button>
          <button (click)="addBlock(row)">Add block</button>
        </div>
      </div>
    </form>

Update to subscribe to valueChanges of formGroup we need change the function newLine and make it in two steps:

newLine()
{
   const group=this.formBuilder.group({
     onValues: [
        { value: "" },
        [Validators.required, Validators.pattern(/^[+-]?\d+(\.\d+)?$/)]
      ],
      ruleTypeValues: [{ value: "" }],
      getType: [{ value: "" }], 
      filterValue: [{ value: "" }]
   })
   group.valuesChange.subscribe((res:any)=>{
     ..here the code
   }
   //or, if we only want to check, e.g. "getType"
   group.get('getType').valueChange.subscribe((res:any)=>{
      ..here the code
   }
   return group;
}

OR, after create the form, e.g. in ngOnInit

ngOnInit()
{
    this.formArray.valueChanges.subcribe((res:any)=>{
       ..here the code..
    }
}

Update2 the newLine function is wrong!!!

must be like

newLine(){
   const group=this.formBuilder.group({
     onValues: ["",
        [Validators.required, Validators.pattern(/^[+-]?\d+(\.\d+)?$/)]
      ],
      ruleTypeValues: [""],
      getType: [""], 
      filterValue: [""]
   })
   return group
}