Dynamic form array with dynamic options

笑着哭i 提交于 2021-02-05 09:29:39

问题


I want to make a student able to choose several workshops in a dynamic number of school subjects

1.- I have a config array, this array have the number of options of the student will choose for every subject

let configarray = {initdate: 2019-07-01, subjectnumber: 4};

In this example for every subject the student will be able to choose 4 options.

let b = this.FormGuardar.get("opciontaller") as FormArray; 
for (let i = 0; i < configarray.subjectnumber; i++) {
     let preregistro = this._fb.group({
         preregistroid: [],
         alumnoporcicloid:[],
         tallercurricularid: []
         });
         b.push(preregistro);
         this.arrayopcion.push({ taller: this.tallerselect }); //tallerselect will display
the options of every subject every subject will have a diferent options

Also when i select a options this is my code for erase the selected option in the other selects in the configurations.

    selectedTaller(id, index) {
    let seleccionados = [];
    let array = this.FormGuardar.get("opciontaller").value;
    for (let a of array) {
        if (a.tallercurricularid) {
            seleccionados.push(a.tallercurricularid);
        }
    }

    let disponibles = this.SelectTaller.filter(function (item) {
        return seleccionados.indexOf(item.tallercurricularid) == -1;
    });

    for (let i = 0; i < this.arrayopcion.length; i++) {
        let data = [...disponibles],
            control = ((this.FormGuardar.controls.opciontaller as FormArray).controls[i] as FormGroup).controls.tallercurricularid as FormControl,
            seleccionado = this.SelectTaller.find(x => x.tallercurricularid == control.value);
        (((this.FormGuardar.controls.opciontaller as FormArray).controls[i] as FormGroup).controls.clasificadorparaescolarid as FormControl).setValue(seleccionado ? seleccionado.clasificadorparaescolaresid.clasificadorparaescolaresid : null);
        seleccionado ? data.push(seleccionado) : null;
        this.arrayopcion[i].taller = data;
        seleccionado ? control.setValue(seleccionado.tallercurricularid) : null;
    }
}

The question here is how can i make this code work for a dynamic number of subjects with a dynamic options for every workshops?


回答1:


To erase the options, see stackoverflow question

If you choose create on-fly the list, you can make something like see stackblitz

You has a recursive function that take as argument an index, an array of controls and an array with the options to choose -in this case I choose between a list of languages-

getLang(i, array, languageList) {
    return i == 0 ? languageList :
      this.getLang(i - 1, array, languageList.filter(x => x.name != array[i - 1].value))
  }

If you has a function like

createStudent() {
  const auxiliar = new Array(this.configarray.subjectNumber).fill('')
    return new FormGroup(
      {
        name: new FormControl(),
        options: new FormArray(auxiliar.map(x => new FormControl()))
      }
    )
  }

You can has in ngOnInit some like

 this.formArray=new FormArray([]);
 this.formArray.push(this.createStudent())
 this.formArray.push(this.createStudent())

And our form is like

<form *ngIf="formArray" [formGroup]="formArray">
    <div *ngFor="let form of formArray.controls">
        <div [formGroup]="form">
            <input formControlName="name">
            <div formArrayName="options">
              <div *ngFor="let a of form.get('options').controls;let i=index" >
                 <select  [formControlName]="i">
                    <option value="null" disabled>Select Language</option>
                    <option *ngFor="let lang of 
                       getLang(i,form.get('options').controls,languageList)"
                       [value]="lang.name" >{{lang.name}}</option>
                </select>
           </div>
        </div>
    </div>
    <hr/>
  </div>
</form>

Updated We need check not possible choose the same language, so we subscribe to changes of the arrays options. So, if we choose e.g. German,Doraki,Spanish and French, and after replace German by Spanish, the 3th options becomes null

this.formArray.controls.forEach(form => {
      form.get('options').valueChanges.subscribe(res => {
        res.forEach((x, index) => {
          if (index > 0 && res.slice(0, index).find(a=>a==x))
            (form.get('options') as FormArray).at(index).setValue(null, { emit: false })
        })
      })
    })


来源:https://stackoverflow.com/questions/57049514/dynamic-form-array-with-dynamic-options

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!