0

Select Box 1 is "Path". Select Box 2 is "SkillSet".

I'm trying to duplicate group of select boxes(Path and SkillSet) based on a button click. So when I click Add button the select box(Path and SkillSet) form element will be duplicated. The catch here is the select box "Skillset" element's options are dynamic because its depends on the select box "Path".

Issue Below: Step1: Choosing Path as BackEnd and Skill will be populated based on the Path. In the second select box selected as Java8.

enter image description here

Step2: Clicking Add button, so the select box Path and Skill is duplicated. Now choosing select box Path as FrontEnd.

enter image description here

Step3: After choosing Path as FrontEnd in the second row, the selected Skill in first row's are reseted to empty. (In the image I have added two Path's)

enter image description here

StackBlitz Demo for the Issue: https://stackblitz.com/edit/angular-duplicate-dynamic-select-box?file=null

Expectation is : I have to select each Path and respective Skill. Like If I choose 3 different path, then I have to choose 3 different skills in the 3 different row of select boxes.

I have tried many solutions. Nothing is working out. Can someone help in this case.?

Sorry for my English and bad formatting. Appreciate your help !!!

3
  • 1
    As I'm not well versed with adding new project to stackblitz, I've added the entire .ts and html code with some modifications in the answer section. Have a look at it. Hope this fulfills your expectation. Commented Feb 9, 2020 at 10:00
  • Thanks for the fix. It worked like charm. This is the stackblitz URL which contains the fix. stackblitz.com/edit/angular-zwhq1r Commented Feb 9, 2020 at 14:34
  • Do mark the answer as accepted so that someone else ma find it useful while searching :) Commented Feb 10, 2020 at 4:16

1 Answer 1

2

You can Push the skillsets for the selected path into an array and access them in the HTML file using the index.

In .ts File

import { Component } from '@angular/core';
import { FormGroup, FormArray, FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  skillSetObj;
  majorPathObj;

  skillForm: FormGroup;
  skillList: FormArray;

  choosenPath;
  skillsForSelectedPath:any = [];  // <--- Declare a new array for the skillsets to be pushed

  constructor(private fb:FormBuilder) {

  }

  ngOnInit() {
    this.skillSetObj = {
      "BackEnd": ["Java8", "Node JS", "Python", "Dotnet"],
      "FrontEnd": ["Javascript ", "Angular ", "React", "Vue"],
      "Database": ["Oracle", "Postgres", "Mysql"]
    };

    this.majorPathObj = ["BackEnd", "FrontEnd", "Database"];

    this.skillForm = this.fb.group({
      skillFormArray: this.fb.array([this.createSkills()])
    });

    this.skillList = this.skillForm.get('skillFormArray') as FormArray;
  }

  createSkills(): FormGroup {
    return this.fb.group({
      majorPath: ['', Validators.compose([Validators.required])],
      skillSet: ['', Validators.compose([Validators.required])]
    });
  }

  getSkillFormGroup(index): FormGroup {
    const formGroup = this.skillList.controls[index] as FormGroup;
    return formGroup;
  }

  get skillFormGroup() {
    return this.skillForm.get('skillFormArray') as FormArray;
  }

  addNewSkill() {
    this.skillList.push(this.createSkills());
  }

  removeSkill(skillRowIndex) {
    this.skillList.removeAt(skillRowIndex);
  }

  prepareSkillSet(event, i) {
    this.skillsForSelectedPath[i]=this.skillSetObj[event.value];  // <--- Push the skills for the selected majorPath into the new array
    const formGroup = this.getSkillFormGroup(i);
    const choosenPath = formGroup.controls['majorPath'].value;
    this.choosenPath = choosenPath;
  }

}

** In HTML file **

<form [formGroup]="skillForm">

  <div formArrayName="skillFormArray">
      <div *ngFor="let skillArray of skillFormGroup.controls; let i=index">
          <div [formGroupName]="i">
              <div >
                  <mat-form-field appearance="outline">
                      <mat-select formControlName="majorPath"
                          (selectionChange)="prepareSkillSet($event, i)">
                          <mat-option *ngFor="let major of majorPathObj" value={{major}}>
                              {{major}}
                          </mat-option>
                      </mat-select>
                  </mat-form-field>
                  <mat-form-field appearance="outline">
                    <mat-select formControlName="skillSet">
                        <mat-option *ngFor="let skill of skillsForSelectedPath[i]" [value]="skill">   <!-- display the skills for the selected majorPath using the index of the newly created variable -->
                            {{skill}}
                        </mat-option>
                    </mat-select>
                </mat-form-field>
                  <button *ngIf="i===0" mat-fab color="accent" class="add-file-button mt-5"
                      (click)="addNewSkill()" aria-label="Add Skill">
                      <mat-icon>add</mat-icon>
                  </button>
                  <button *ngIf="i!==0" mat-fab color="warn" class="add-file-button"
                      (click)="removeSkill(i)" aria-label="Remove Skill">
                      <mat-icon>remove</mat-icon>
                  </button>
              </div>

          </div>

      </div>
  </div>
</form>

So everytime the majorPath is the skills object is also updated and you can select the corresponding skills for the newly selected majorPath.

The output looks like below

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

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.