Getting Started with Kendo UI for Angular FormField

The FormField enables you to group and provide configurable behavior of form-related content like inputs, labels, hint and error messages and supports both Reactive and Template-Driven Angular forms.

Each kendo-formfield element can contain a single form control element, a label and multiple hint or error messages. The only exception to this rule is a RadioButton group.

Basic Usage

The following example demonstrates the FormField component within a Reactive Angular form in action.

import { Component, ViewEncapsulation } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';

@Component({
    selector: 'my-app',
    template: `
        <div class="example-wrap">
            <form class="k-form" [formGroup]="registerForm">
                <fieldset class="k-form-fieldset">
                    <legend class="k-form-legend">User Details</legend>
                    <kendo-formfield>
                        <kendo-label [for]="firstName" text="First Name"></kendo-label>
                        <input formControlName="firstName" kendoTextBox #firstName required/>

                        <kendo-formhint>Your first name</kendo-formhint>
                        <kendo-formerror>Error: First name is required</kendo-formerror>
                    </kendo-formfield>

                    <kendo-formfield>
                        <kendo-label [for]="lastName" text="Last Name"></kendo-label>
                        <input formControlName="lastName" kendoTextBox #lastName required/>

                        <kendo-formhint>Your last name</kendo-formhint>
                        <kendo-formerror>Error: Last name is required</kendo-formerror>
                    </kendo-formfield>

                    <kendo-formfield>
                        <kendo-label [for]="birthDate" [optional]="true" text="Birth Date"></kendo-label>
                        <kendo-datepicker
                            #birthDate
                            formControlName="birthDate"
                            [min]="min"
                            [max]="max"
                        >
                        </kendo-datepicker>

                        <kendo-formhint>Your birth date</kendo-formhint>
                    </kendo-formfield>


                    <kendo-formfield>
                        <kendo-label [for]="email" text="Email"></kendo-label>
                        <input formControlName="email" kendoTextBox #email required/>

                        <kendo-formhint>Your active email</kendo-formhint>
                        <kendo-formerror>Error: Not valid email format</kendo-formerror>
                    </kendo-formfield>

                    <kendo-formfield>
                        <div class="k-checkbox-wrap">
                            <input #acceptNews type="checkbox" kendoCheckBox formControlName="acceptNews"/>
                            <kendo-label [for]="acceptNews" class="k-checkbox-label" text="I want to receive notifications"></kendo-label>
                        </div>

                        <kendo-formhint>You will receive our latest updates and promotions on your email</kendo-formhint>
                    </kendo-formfield>

                    <div class="k-form-buttons">
                        <button class="k-button k-primary" (click)="submitForm()">Submit</button>
                        <button class="k-button" (click)="clearForm()">Clear</button>
                    </div>
                </fieldset>
            </form>
        </div>
    `,
    styles: [`
        .example-wrap {
            display: flex;
            justify-content: center;
        }
        .k-form {
            width: 400px;
        }

    `],
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    public min: Date = new Date(1917, 0, 1);
    public max: Date = new Date(2020, 4, 31);

    public registerForm: FormGroup = new FormGroup({
        firstName: new FormControl(),
        lastName: new FormControl(),
        birthDate: new FormControl(new Date(2000, 10, 10)),
        email: new FormControl('', Validators.email),
        acceptNews: new FormControl()
    });

    public submitForm(): void {
        this.registerForm.markAllAsTouched();
    }

    public clearForm(): void {
        this.registerForm.reset();
    }
}
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { DateInputsModule } from '@progress/kendo-angular-dateinputs';
import { LabelModule } from '@progress/kendo-angular-label';
import { InputsModule } from '@progress/kendo-angular-inputs';
import { AppComponent } from './app.component';

@NgModule({
    bootstrap:    [AppComponent],
    declarations: [AppComponent],
    imports:      [
        BrowserModule,
        BrowserAnimationsModule,
        FormsModule,
        ReactiveFormsModule,
        DateInputsModule,
        InputsModule,
        LabelModule
    ]
})
export class AppModule { }

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

The following example demonstrates the FormField component within a Template-Driven Angular form in action.

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

@Component({
    selector: 'my-app',
    template: `
      <form class="k-form">
        <kendo-formfield>
            <kendo-label [for]="firstName" text="First Name"></kendo-label>
            <input kendoTextBox name="name" [(ngModel)]="name" #firstName required/>

            <kendo-formhint>Your first name</kendo-formhint>
            <kendo-formerror>Error: First name is required</kendo-formerror>
        </kendo-formfield>
        <kendo-formfield>
            <kendo-label [for]="birthDatePicker" [optional]="true" text="Birth Date"></kendo-label>
            <kendo-datepicker
                #birthDatePicker
                name="birthDate"
                [(ngModel)]="birthDate"
                [min]="min"
                [max]="max"
            >
            </kendo-datepicker>

            <kendo-formhint>Your birth date</kendo-formhint>
        </kendo-formfield>

      </form>
    `
})
export class AppComponent {
    name = 'John Doe';
    birthDate: Date;
    min = new Date(1917, 0, 1);
    max = new Date(2020, 4, 31);
}
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { DateInputsModule } from '@progress/kendo-angular-dateinputs';
import { LabelModule } from '@progress/kendo-angular-label';
import { InputsModule } from '@progress/kendo-angular-inputs';
import { AppComponent } from './app.component';

@NgModule({
    bootstrap:    [AppComponent],
    declarations: [AppComponent],
    imports:      [
        BrowserModule,
        BrowserAnimationsModule,
        FormsModule,
        ReactiveFormsModule,
        DateInputsModule,
        InputsModule,
        LabelModule
    ]
})
export class AppModule { }

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Hints and Errors

Hint and error messages can be displayed by adding HintComponent or ErrorComponent instances inside the FormField component.

Default Setup

By default, the errors are hidden and will be displayed when the form control is invalid after user interaction.
If provided, the hints are initially visible and will hide if an error appears.

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
    selector: 'my-app',
    template: `
        <div class="example-wrap">
            <account-form></account-form>
        </div>
    `,
    styles: [`
        .example-wrap {
            display: flex;
            justify-content: center;
        }

    `],
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {}
import { Component, ViewEncapsulation } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';

@Component({
    selector: 'account-form',
    template: `
        <form class="k-form" [formGroup]="userForm">
            <fieldset class="k-form-fieldset">
                <legend class="k-form-legend">Account Details</legend>
                <kendo-formfield [showHints]="'initial'" [showErrors]="'initial'">
                    <kendo-label [for]="userName" text="Username"></kendo-label>
                    <input formControlName="userName" kendoTextBox #userName required/>

                    <kendo-formhint>Your username</kendo-formhint>
                    <kendo-formerror>Error: Username is required</kendo-formerror>
                </kendo-formfield>

                <kendo-formfield [showHints]="'initial'" [showErrors]="'initial'">
                    <kendo-label [for]="email" text="Email" [optional]="true"></kendo-label>
                    <input formControlName="email" kendoTextBox #email />

                    <kendo-formhint>Your email address</kendo-formhint>
                    <kendo-formerror>Error: Not valid email format</kendo-formerror>
                </kendo-formfield>

            </fieldset>
        </form>
    `,
    styles: [`
        .k-form {
            width: 400px;
        }

    `],
    encapsulation: ViewEncapsulation.None
})
export class AccountFormComponent {

    public userForm: FormGroup = new FormGroup({
        userName: new FormControl(),
        email: new FormControl('', Validators.email)
    });
}
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { LabelModule } from '@progress/kendo-angular-label';
import { InputsModule } from '@progress/kendo-angular-inputs';
import { AppComponent } from './app.component';

import { AccountFormComponent } from './account-form.component';

@NgModule({
    bootstrap:    [AppComponent],
    declarations: [AppComponent, AccountFormComponent],
    imports:      [
        BrowserModule,
        BrowserAnimationsModule,
        FormsModule,
        ReactiveFormsModule,
        InputsModule,
        LabelModule
    ]
})
export class AppModule { }

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Managing Visibility

The FormField component provides control for hint and error messages by setting showHints and showErrors properties.

The available showHints values are:

  • (Default) initial—Allows displaying hints when the form-bound component state is valid or untouched and pristine.
  • always—Allows full control over the visibility of the hints.

The available showErrors values are:

  • (Default) initial—Allows displaying errors when the form-bound component state is invalid and touched or dirty.
  • always—Allows full control over the visibility of the errors.
import { Component, ViewEncapsulation } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';

@Component({
    selector: 'my-app',
    template: `
        <div class="example-wrap">
            <form class="k-form" [formGroup]="userForm">
                <fieldset class="k-form-fieldset">
                    <legend class="k-form-legend">Account Details</legend>
                    <kendo-formfield [showHints]="'always'" [showErrors]="'initial'">
                        <kendo-label [for]="userName" text="Username"></kendo-label>
                        <input formControlName="userName" kendoTextBox #userName required/>

                        <kendo-formhint>Username has to be at least 3 characters</kendo-formhint>
                        <kendo-formerror *ngIf="userForm.controls.userName.errors?.required">Error: Username is required</kendo-formerror>
                        <kendo-formerror *ngIf="userForm.controls.userName.errors?.minlength">Error: Username has to be at least 3 characters</kendo-formerror>
                    </kendo-formfield>

                    <kendo-formfield [showHints]="'initial'" [showErrors]="'always'">
                        <kendo-label [for]="email" text="Email"></kendo-label>
                        <input formControlName="email" kendoTextBox #email required/>

                        <kendo-formhint>Your email address</kendo-formhint>
                        <kendo-formerror *ngIf="(userForm.controls.email.touched || userForm.controls.email.dirty) && userForm.controls.email.errors?.required">Error: Email is required</kendo-formerror>
                        <kendo-formerror *ngIf="userForm.controls.email.errors?.email">Error: Not valid email format</kendo-formerror>
                    </kendo-formfield>

                </fieldset>
            </form>
        </div>
    `,
    styles: [`
        .example-wrap {
            display: flex;
            justify-content: center;
        }
        .k-form {
            width: 400px;
        }

    `],
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {

    public userForm: FormGroup = new FormGroup({
        userName: new FormControl('', Validators.minLength(3)),
        email: new FormControl('', Validators.email)
    });
}
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { LabelModule } from '@progress/kendo-angular-label';
import { InputsModule } from '@progress/kendo-angular-inputs';
import { AppComponent } from './app.component';

@NgModule({
    bootstrap:    [AppComponent],
    declarations: [AppComponent],
    imports:      [
        BrowserModule,
        BrowserAnimationsModule,
        FormsModule,
        ReactiveFormsModule,
        InputsModule,
        LabelModule
    ]
})
export class AppModule { }

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Alignment

Both the HintComponent and ErrorComponent allows you to specify text alignment by setting the align property.

import { Component, ViewEncapsulation } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';

@Component({
    selector: 'my-app',
    template: `
        <div class="example-wrap">
            <form class="k-form" [formGroup]="userForm">
                <kendo-formfield>
                    <kendo-label [for]="userName" text="Username"></kendo-label>
                    <input formControlName="userName" kendoTextBox #userName required/>

                    <kendo-formhint [align]="'start'">Your username</kendo-formhint>
                    <kendo-formerror [align]="'end'">Error: Username is required</kendo-formerror>
                </kendo-formfield>
            </form>
        </div>
    `,
    styles: [`
        .example-wrap {
            display: flex;
            justify-content: center;
        }
        .k-form {
            width: 400px;
        }

    `],
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {

    public userForm: FormGroup = new FormGroup({
        userName: new FormControl()
    });
}
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { LabelModule } from '@progress/kendo-angular-label';
import { InputsModule } from '@progress/kendo-angular-inputs';
import { AppComponent } from './app.component';

@NgModule({
    bootstrap:    [AppComponent],
    declarations: [AppComponent],
    imports:      [
        BrowserModule,
        BrowserAnimationsModule,
        FormsModule,
        ReactiveFormsModule,
        InputsModule,
        LabelModule
    ]
})
export class AppModule { }

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Horizontal Fields

The FormField component provides an option for changing the layout of its content by setting the orientation property to horizontal.

import { Component, ViewEncapsulation } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';

@Component({
    selector: 'my-app',
    template: `
        <form class="k-form k-form-horizontal" [formGroup]="userForm">
            <fieldset class="k-form-fieldset">
                <legend class="k-form-legend">Account Details</legend>
                <kendo-formfield [orientation]="'horizontal'">
                    <kendo-label [for]="userName" text="Username"></kendo-label>
                    <input formControlName="userName" kendoTextBox #userName required/>

                    <kendo-formhint>Your username</kendo-formhint>
                    <kendo-formerror>Error: Username is required</kendo-formerror>
                </kendo-formfield>

                <kendo-formfield [orientation]="'horizontal'">
                    <kendo-label [for]="email" text="Email"></kendo-label>
                    <input formControlName="email" kendoTextBox #email />

                    <kendo-formhint>Your email address</kendo-formhint>
                    <kendo-formerror *ngIf="userForm.controls.email.errors?.email">Error: Not valid email format</kendo-formerror>
                    <kendo-formerror *ngIf="userForm.controls.email.errors?.required">Error: Username is required</kendo-formerror>
                </kendo-formfield>

            </fieldset>
        </form>
    `,
    styles: [`
        .k-form {
            width: 400px;
        }

    `],
    encapsulation: ViewEncapsulation.None
})
export class AppComponent {

    public userForm: FormGroup = new FormGroup({
        userName: new FormControl(),
        email: new FormControl('', [Validators.required, Validators.email])
    });
}
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { LabelModule } from '@progress/kendo-angular-label';
import { InputsModule } from '@progress/kendo-angular-inputs';
import { AppComponent } from './app.component';

@NgModule({
    bootstrap:    [AppComponent],
    declarations: [AppComponent],
    imports:      [
        BrowserModule,
        BrowserAnimationsModule,
        FormsModule,
        ReactiveFormsModule,
        InputsModule,
        LabelModule
    ]
})
export class AppModule { }

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

In this article