1

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);
    }
    

    '

user21
  • 1,261
  • 5
  • 20
  • 41
  • 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 Apr 14 '20 at 06:34
  • Hi Kurt, I've created a stackblitz. https://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 list – user21 Apr 14 '20 at 07:29

1 Answers1

1

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
}
Eliseo
  • 50,109
  • 4
  • 29
  • 67
  • I have tried implementing the formGroup but runs into issue whether it doesn't recognize the formGroup.valueChages() in the constructor and other issues. I'm struggling with that, trying to read a lot of article on formGroup and formControl but the concept is new to me, is it possible if anybody could suggest / edit the code posted at stackblitz . Thanks in advance. – user21 Apr 14 '20 at 17:39
  • you need subscribe to formGroup.valueChanges, AFTER create the formGroup, I updated the answer – Eliseo Apr 15 '20 at 09:20
  • Please see my revised code at https://stackblitz.com/edit/angular-eazn5i. I tried the subscription to formGroup.value changes (line 52-58 of app.component.ts at stackblitz) but it doesn't work. I have to comment it and use (line 46-49 of app.component.ts at stackblitz) for loop to loop through the formArray but it doesn't seems to be able to detect changes in the formControlName either. If you have any idea, would greatly appreciate that. Would like to modify the specific formgroupname for that particular row (specific index of formArray). https://stackblitz.com/edit/angular-eazn5i. – user21 Apr 15 '20 at 19:03
  • @user21, sorry, the function "newLine" it was wrong. I forked your stackblitz in https://stackblitz.com/edit/angular-fxhbhi?file=src/app/app.component.html. See that ruleForm is a FormArray and I iterate over. the "key" is the `let row of ruleForm.controls [formGroup]="row"` this "strange" way to show the array -normally you see formArrayName and formGroupName-, but you has directly a formArray. Another important thing is that `getValues` is an array. else you can not make severals lines. futhermore the `setValues` function need received the "group" and the "index" that we change – Eliseo Apr 16 '20 at 12:03