How to add reactive forms within Tab in Angular Tab

31 Aug 202624 minutes to read

The Tab component supports rendering other components inside Tab panels using Angular ng-template. This includes integrating reactive forms within individual tab items to create organized, multi-section form interfaces.

For more details about Reactive Forms refer: https://angular.io/guide/reactive-forms.

To implement reactive forms within tabs:

  1. Import ReactiveFormsModule into the app module.
  2. Import FormGroup and FormControl into the component file.
  3. Bind each FormControl to a form element (e.g., AutoComplete).
  4. Reference the FormGroup directly within the ng-template to render the form content inside the tab panel.

Form state preservation: When loadOn is set to Dynamic, the form values are reset on every selection. For state preservation across tab switches, use the default OnDemand or Init rendering modes. See Content Render Modes.

The following example demonstrates how to add reactive forms within a Tab item using ng-template.

import { NgModule } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { TabModule } from '@syncfusion/ej2-angular-navigations'
import { AutoCompleteModule } from '@syncfusion/ej2-angular-dropdowns'
import { DropDownListModule } from '@syncfusion/ej2-angular-dropdowns'
import { ButtonModule } from '@syncfusion/ej2-angular-buttons'




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


@Component({
imports: [  FormsModule, ReactiveFormsModule, AutoCompleteModule, DropDownListModule, ButtonModule,TabModule ],


standalone: true,
    selector: 'app-container',
    template: `
    <ejs-tab id="element" #tab>
    <e-tabitems>
        <e-tabitem [header]='headerText[0]'>
            <ng-template #content>
                <div id="reactive-form">
                    <div class="control-section">
                        <div class="col-lg-8  content-wrapper">
                            <div id='content' class='box-form' style="margin: 0 auto; width:250px; padding:25px">
                                <form [formGroup]="skillForm" novalidate id="formId">
                                    <div class="form-group">
                                        <ejs-autocomplete formControlName="skillname" name="skillname"
                                            [dataSource]='skillset' allowCustom=false [placeholder]='placeholder'
                                            floatLabelType='Auto'>
                                        </ejs-autocomplete>
                                    </div>
                                    <div class="form-group" style="padding-top:10px;">
                                        <div class="e-float-input">
                                            <input type="text" autocomplete="off" (focus)="onfocus($event)"
                                                (blur)="onblur($event)" formControlName="sname" name="sname"
                                                maxlength="10" />
                                            <span class="e-float-line"></span>
                                            <label class="e-float-text e-label-bottom">Name:</label>
                                        </div>
                                    </div>
                                    <div class="form-group" style="padding-top:10px;">
                                        <div class="e-float-input">
                                            <input type="text" autocomplete="off" (focus)="onfocus($event)"
                                                (blur)="onblur($event)" formControlName="smail" maxlength="15" />
                                            <span class="e-float-line"></span>
                                            <label class="e-float-text e-label-bottom">Email:</label>
                                        </div>
                                    </div>
                                    <div class="form-group" style="padding:10px;">
                                        <div class="col-xs-6 col-sm-6 col-lg-6 col-md-6">
                                            <button ejs-button [disabled]="!skillForm.valid">Done</button></div>
                                        <div class="col-xs-6 col-sm-6 col-lg-6 col-md-6">
                                            <button ejs-button type="reset" (click)="onreset($event)">Cancel</button>
                                        </div>
                                    </div>
                                </form>
                            </div>
                        </div>
                        <div class="col-lg-4 property-section">
                            <div class="property-panel-section">
                                <div class="property-panel-header">Properties</div>
                                <div class="property-panel-content" style="padding: 10px;">
                                    <table id="property" class="box-table" title="Properties" style="width: 100%;">
                                        <tr>
                                            <td style="width:50%">Selected Language: </td>
                                            <td class="formtext"></td>
                                        </tr>
                                        <tr>
                                            <td style="width:50%">Buyer Name: </td>
                                            <td class="formtext"></td>
                                        </tr>
                                        <tr>
                                            <td style="width:50%">Buyer Mail ID: </td>
                                            <td class="formtext"></td>
                                        </tr>
                                    </table>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </ng-template>
        </e-tabitem>
        <e-tabitem [header]='headerText[1]'>
            <ng-template #content>
                <div class="row" style="width:500px;">
                    <div class="col-xs-7 col-sm-7 col-lg-7 col-md-7" style="padding-top:20px;">
                        <div style="webkit-box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2);
     box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2);
     margin:0 auto;height:330px;">
                            <div style="padding:30px;">
                                <form #form="ngForm">
                                    <div class="form-group">
                                        <ejs-dropdownlist name="skillname" formControlName="skillname"
                                            [dataSource]='skillset' [placeholder]='placeholder' floatLabelType='Auto'>
                                        </ejs-dropdownlist>
                                    </div>
                                    <div class="form-group" style="padding-top:10px;">
                                        <div class="e-float-input">
                                            <input type="text" formControlName="sname"
                                                maxlength="10" />
                                            <span class="e-float-line e-label-top"></span>
                                            <label class="e-float-text e-label-top">Name:</label>
                                        </div>
                                    </div>
                                    <div class="form-group" style="padding-top:10px;">
                                        <div class="e-float-input">
                                            <input type="text" formControlName="smail"
                                                maxlength="15" />
                                            <span class="e-float-line e-label-top"></span>
                                            <label class="e-float-text e-label-top">Email:</label>
                                        </div>
                                    </div>
                                    <div class="form-group" style="padding:10px;">
                                        <button ejs-button>Done</button>
                                        <button ejs-button type="reset">Cancel</button>
                                    </div>
                                </form>
                            </div>
                        </div>
                    </div>
                    <div class="col-xs-5 col-sm-5 col-lg-5 col-md-5" style="padding-top:20px;">
                        <div style="webkit-box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2);
     box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.12), 0 1px 5px 0 rgba(0,0,0,0.2);
     margin:0 auto;height:330px;">
                            <div style="padding:30px;">
                                <div class="form-group">
                                    <span style="font-weight:800;">Selected Language: </span>
                                    <span style="font-style:oblique;color:#8a2be2;">
                                        </span>
                                </div>
                                <div class="form-group" style="padding-top:50px;">
                                    <span style="font-weight:800;">Buyer Name: </span>
                                    <span style="font-style:oblique;color:#8a2be2;">
                                        </span>
                                </div>
                                <div class="form-group" style="padding-top:50px;">
                                    <span style="font-weight:800;">Buyer Mail ID: </span>
                                    <span style="font-style:oblique;color:#8a2be2;">
                                        </span>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </ng-template>
        </e-tabitem>

    </e-tabitems>
</ejs-tab>
`
})

export class AppComponent {
    public headerText: Object | any = [{ 'text': 'ReactiveForms1' }, { 'text': 'ReactiveForms2' }];

    public skillset: string[] = [
        'ASP.NET', 'ActionScript', 'Basic',
        'C++', 'C#', 'dBase', 'Delphi',
        'ESPOL', 'F#', 'FoxPro', 'Java',
        'J#', 'Lisp', 'Logo', 'PHP'
    ];

    

    public placeholder: String = 'Select a language';
    public skillForm!: FormGroup;

    constructor(@Inject(FormBuilder) private builder: FormBuilder) {
        this.createForm();
    }

    createForm(): void {
        this.skillForm = this.builder.group({
            skillname: ['', Validators.required],
            sname: ['', Validators.required],
            smail: ['', Validators.required]
        });
    }

    onfocus(element: FocusEvent): void {
        let target: HTMLInputElement = element.target as HTMLInputElement;
        let parentNode: HTMLElement = target.parentNode as HTMLElement;
        if (parentNode.classList.contains('e-input-in-wrap')) {
            parentNode = (parentNode.parentNode as HTMLElement);
        }
        parentNode.classList.add('e-input-focus');
        (parentNode.children[2] as Element).classList.add('e-label-top');
        (parentNode.children[2] as Element).classList.remove('e-label-bottom');

    }
    onblur(element: FocusEvent): void {
        let target: HTMLInputElement = element.target as HTMLInputElement;
        let parentNode: HTMLElement = target.parentNode as HTMLElement;
        if (parentNode.classList.contains('e-input-in-wrap')) {
            (parentNode.parentNode as HTMLElement).classList.remove('e-input-focus');
        }
        parentNode.classList.remove('e-input-focus');
        if (target.value === null || target.value === '') {
            (parentNode.children[2] as Element).classList.remove('e-label-top');
            (parentNode.children[2] as Element).classList.add('e-label-bottom');
        } else {
            (parentNode.children[2] as Element).classList.add('e-label-top');
            (parentNode.children[2] as Element).classList.remove('e-label-bottom');
        }
    }
    onreset(element: MouseEvent): void {
        let parentNode: NodeListOf<HTMLElement> = document.getElementsByClassName('box-form')[0].querySelectorAll('.e-float-text');
        for (let i: number = 0; i < parentNode.length; i++) {
            parentNode[i].classList.remove('e-label-top');
            parentNode[i].classList.add('e-label-bottom');
        }
    }
}
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));

See Also