0

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.

1
  • I have tried to create another interface called ALLTABTYPES but it is not getting mapped with tabstype interface. Commented Feb 20, 2018 at 13:21

1 Answer 1

1

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>
Sign up to request clarification or add additional context in comments.

11 Comments

Hey Richardo, Thanks for your answer. You mean to say that instead of creating formarray from formgroups, I should create formgroups from form array which are already nested? Also I should use formbuilder for that?
Ok so How will I access this nested strucuture in html? just like the way I have done???
yes, I really love use reactive form, and the formbuilder help me a lot to create my reactive form, I think is going to be more clean to handle... something that you need to have present is when you going to get the data from the form, the values are going to be separated by tabs
Yup so that can be taken care by appending each tabs value to one common array or string and then can be send as json. My only doubt is will the ng-formly tool I am using will accept the form model or not? How will I parse that in html??
I hope the html example that I add will help you to undertand
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.