How to create multidimensional angular 4 FormArray?

I am creating dynamic form using ng-formly npm tool. I want this form to be devided in sections and tabs but still having one submit button. ie single tag. Now I as per the documentation of that library. I have created this interface called TabType which holds diff fields for a particular tab.

      export interface TabType {
            label: string;
           fields: FormlyFieldConfig[]
        }

Now Using the below variables and schema I am able to generate the form which is divided in to different sections using above TabType interface.

       form = new FormGroup({});
      model = {};
           options: FormlyFormOptions = {};


       tabs: TabType[] = [
{
  label: 'Personal data',
  fields: [

      {
        className: '',
        template: '<strong>Basic Information:</strong>',
      },

         {
            fieldGroupClassName: '',
            fieldGroup: [
              {
                className: 'mdc-text-field__input',
                type: 'input',
                key: 'firstName',
                templateOptions: {
                  label: 'First Name',
                },
               },

              {
                className: 'mdc-text-field__input',
                type: 'input',
                key: 'lastName',
                templateOptions: {
                  label: 'Last Name',
                },
                expressionProperties: {
                  'templateOptions.disabled': '!model.firstName',
                },
              },
            ],
        },


{
  className: '',
  template: '<strong>Address:</strong>',
},
{
  fieldGroupClassName: '',
  fieldGroup: [
    {
      className: 'row',
      type: 'input',
      key: 'street',
      templateOptions: {
        label: 'Street',
      },
    },
    {
      className: 'mdc-text-field__input',
      type: 'input',
      key: 'cityName',
      templateOptions: {
        label: 'City',
      },
    },
    {
      className: 'mdc-text-field__input',
      type: 'input',
      key: 'zip',
      templateOptions: {
        type: 'number',
        label: 'Zip',
        max: 99999,
        min: 0,
        pattern: '\\d{5}',
      },
    },
  ],
},


 {
  className: '',
  template: '<strong>Other Inputs:</strong>',
},
{
  type: 'textarea',
  key: 'otherInput',
  templateOptions: {
    label: 'Other Input',
  },
},
{
  type: 'checkbox',
  key: 'otherToo',
  templateOptions: {
    label: 'Other Checkbox',
  },
},


  ],
},


{
  label: 'Destination',
  fields: [
    {
      key: 'country',
      type: 'input',
      templateOptions: {
        label: 'Country',
        required: true,
      },
    },
  ],
},
{
  label: 'Day of the trip',
  fields: [
    {
      key: 'day',
      type: 'input',
      templateOptions: {
        type: 'date',
        label: 'Day of the trip',
        required: true,
      },
    },
  ],
},
 ];

Now after creating this variable I am creating One FormArray called 'form' like this,

      form = new FormArray(this.tabs.map(() => new FormGroup({})));

Finally in HTML file I have below code which parse through the tab as well TabType called 'tabs' array and access the desired form fields to render it.

                     <div class="mdc-card">
                          <section class="mdc-card__primary view-section">
                              <h3>{{tab.label}}</h3>
                          </section>
                          <section class="mdc-card__supporting-text view-section-body">

                               <formly-form 
                                [form]="form.at(index)"
                                [model]="model"
                                [fields]="tab.fields"
                                [options]="options">
                              </formly-form>

                          </section>
                      </div>
                  </div>

Now I want to do one more iteration over the form elements and want to divide the fields in tabs. In above you can see it is creating sections.

So What I see the problem is that if we can create multidimensional FormArray, then we might iterate it using tab lists, the we done using sections list above.

Can someone Please suggest me the way to do it?

Update :

        form = new FormArray(this.tabs.map(() => new FormGroup({})));

               const baseForm: FormGroup = this.fb.group({
         tabs: this.fb.array([this.form,this.form,this.form])
          }) 

Now the above baseForm have all three tabs data (though identical), Can you help to get it pass it as array so that I can iterate through it, Because I Dont think I am able to iterate formgroup object in html.

Upvotes: 0

Views: 2428

Answers (1)

Ricardo
Ricardo

Reputation: 2487

You should divide your form in tabs, let say, your base form will look like this:

// fb: FormBuilder     
const baseForm: FormGroup = this.fb.group({})

your main goal is divide your form in tabs so is necessary iterate over all your tabs, thats why you need a tab array inside your form

const baseForm: FormGroup = this.fb.group({
    tabs: this.fb.array([])
})

this form array should have inside all the field that belongs to your specific tab... it will contain a list of form groups

const baseForm: FormGroup = this.fb.group({
    tabs: this.fb.array([
       this.fb.group({
         f1: this.fb.control("value"),
         g2: this.fb.group({ 
           f2: this.fb.control("value")
         }),
         a3: this.form.array([])
       })
    ])
})

this solution is using ReactivesFormsModule

EDIT: the html will look like

<form class="ui form form-group" [formGroup]="baseForm">
  <div formArrayName="tabs">
    <div *ngFor="let tabGroup of tabs.controls; let i=index" [formGroupName]="i">
     <input type="text" formControlName="f1">
     <div [formGroup]="g2">
        <input type="text" formControlName="f2">
     </div>
      <div formArrayName="a3">
       .....// other form group
      </div>
   </div>
  </>
</form>

Upvotes: 1

Related Questions