简体   繁体   中英

How to generate dynamic tab based on API data in Angular

I have below json response.

From json response i am creating dynamic tab and inside every tab i want to push formArray based on below mentioned condition.

**In below response,

 const myObj = [
          {
            'TabName': 'Test1',
            'otherDetails': [
              {
                'processTechType': 'Continuous'
              },
              {
                'processTechType': 'Batch',
              },
            ]
          },
          {
            'TabName': 'Test2',
            'otherDetails': [
              {
                'processTechType': 'Batch'
              }
            ]
          }
        ];

For Ex -** TabName Test1 and TabName Test2 are tabs name which i am displaying dynamically. Now in Test1 Tab , i want to push formArray Continuous and formArray Batch both forms. Because in Test1 Tab, i have processTechType array with Continuous and batch both. So it will show both form in Test1 Tab.

Ex - 2 -- Now in Test2 Tab, i want to push formArray Batch form only. Becuase in Test2 Tab, i have processTechType batch in otherDetails object. So it will show Batch form only in Test2 Tab.

My mean to say is everytime it will check the Tabname and otherDetails key from response and show forms based on processTechType array key on specific tab only.

I have below code. But it is pushing both forms in all tabs, not on specific tab. For ex - From my code, It is showing Continuous formArray onetime and Batch formArray two times in Test1 and Test2 tabs both.

Expected output -

In Test1 Tab, it will push one Continuous and one Batch form.

In Test2 Tab, It will show push batch form only.

Can anyone please help me get my code work to get my expected output.

getMakeLineData() {
    
    var otherDetails = myObj.filter(m => m.otherDetails).map(m => m.otherDetails);
    this.makeLineData = myObj;
    if (otherDetails) {
      otherDetails.forEach(element => {       
        for (var i of element) {
          if (i.processTechType === 'Continuous') {
            this.addQuantity();
          }
          else if (i.processTechType === 'Batch')  {
            this.addBatch();
          } 
        }
      });      
    } 
}

createContinuousForm() {
    return this.fb.group({
      designProcess: ['', [Validators.required]]
    });
  }
  createBatchForm() {
    return this.fb.group({
      avgBCT: ['', [Validators.required]]
    });
  } 
  continuousType(): FormArray {
    return this.dataCollectionForm.get("continuousType") as FormArray;
  }

  batchType(): FormArray {
    return this.dataCollectionForm.get("batchType") as FormArray;
  }

  addQuantity() {
    this.continuousType().push(this.createContinuousForm());

  }
  addBatch() {
    this.batchType().push(this.createBatchForm());
  }

HTML form template

<div class="tabGroupDiv row">
    <div class="lossLinesDiv">     
      <mat-tab-group class="lossMatGrpCls" mat-align-tabs="left">
        <mat-tab *ngFor="let lineData of makeLineData">
          <ng-template mat-tab-label>
                <button class="validatorTabBgClr">{{lineData.makeLineName}}</button>
          </ng-template>
          <form [formGroup]="dataCollectionForm" (ngSubmit)="onSubmit()">
            <!-- <--continuous Form start here -->  
            <div class="admin-console-main-wrapper" formArrayName="continuousType">
              <div class="content-wrapper" *ngFor="let lineItem of continuousType().controls; let i=index"
                [formGroupName]="i">
              
                <div class="row list-wrapper">
                  <div class="col-xs-3 col-md-3 deo-dv-list-wrapper">
                    <h5 class="topbar-items-text">Design Process Capacity (Tonnes)</h5>
                    <mat-form-field appearance="outline">
                      <input matInput type="text" class="line-fte-input smed-input" placeholder="Design Process Capacity"
                        formControlName="designProcess">
                    </mat-form-field>
                    <mat-error *ngIf="lineItem?.controls?.designProcess?.hasError('required')">
                      Field is required
                    </mat-error>
                  </div>
                </div>              
              </div>
            </div>  
            <!-- <--continuous Form start here -->
  
            <!-- <--Batch Form start here -->
            <div class="admin-console-main-wrapper" formArrayName="batchType">
              <div class="content-wrapper" *ngFor="let lineBatchItem of batchType().controls; let i=index"
                [formGroupName]="i">               
  
                <div class="row list-wrapper">
                  <div class="col-xs-3 col-md-3 deo-dv-list-wrapper">
                    <h5 class="topbar-items-text">Average BCT (mins)</h5>
                    <mat-form-field appearance="outline">
                      <input matInput type="text" class="line-fte-input smed-input" placeholder="Average BCT"
                        formControlName="avgBCT">
                    </mat-form-field>
                  </div>                 
                </div>
              </div>
            </div>  
            <!-- <--Batch Form ends here -->
          </form>
        </mat-tab>
      </mat-tab-group>
    </div>
  </div>

The structure has been written for one dataCollectionForm not multiple. What is mean is there is seperation of dataCollectionForm by tabs. Unless on change of tab you recreate the form, this should not work.

  1. dataCollectionForm should be a collection of form group, by some id.
  2. Don't over complicate with in correct user of filter and map

Sudo Code below, might need correction, just there to give you direction:

 public makeLineData: any[] = []; // object with otherDetails

   // will contain form based on myObj index
   public dataCollectionForm: FormGroup[] = []; // in template loop over this by index

 createForm() { // getMakeLineData name correction

    myObj
   .filter(m => m.otherDetails)
   .forEach((obj) => {
     // create and push From in dataCollectionForm
     this.makeLineData.push(obj);
     let dataFrom =  this.addTabDataCollectionForm();

     obj.otherDetails.forEach((detail) => {
       if (detail.processTechType === 'Continuous') {
            this.addQuantity(dataFrom);
          }
          else if (detail.processTechType === 'Batch')  {
            this.addBatch(dataFrom);
          } 
     })

   
   })

    var otherDetails = myObj.filter(m => m.otherDetails).map(m => m.otherDetails);
    this.makeLineData = myObj;
    if (otherDetails) {
      otherDetails.forEach(element => {       
        for (var i of element) {
          if (i.processTechType === 'Continuous') {
            this.addQuantity();
          }
          else if (i.processTechType === 'Batch')  {
            this.addBatch();
          } 
        }
      });      
    } 
}

addTabDataCollectionForm (): FromGroup {
  // this will represet the form of one single tab;
  let tabDataForm = this.fb.group({
      continuousType: new FormArray([])
      batchType: new FormArray([])
    });

    this.dataCollectionForm.push(tabDataForm); 
    return tabDataForm; 
    
}

createContinuousForm() {
    return this.fb.group({
      designProcess: ['', [Validators.required]]
    });
  }
  createBatchForm() {
    return this.fb.group({
      avgBCT: ['', [Validators.required]]
    });
  } 

  continuousType(dataFrom): FormArray {
    return dataFrom.get("continuousType") as FormArray;
  }

  batchType(dataFrom): FormArray {
    return dataFrom.get("batchType") as FormArray;
  }

  addQuantity(dataFrom) {
    this.continuousType(dataFrom).push(this.createContinuousForm());

  }
  addBatch(dataFrom) {
    this.batchType(dataFrom).push(this.createBatchForm());
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM