Step Validation

The Stepper enables you to set validation logic for each step. Based on it, a success or error icon will be rendered for previous steps (whose index is less than the index of the current step). Validation icons are rendered either in the step indicator or as part of the step label, depending on the current Stepper configuration options.

By default the validation logic is executed only for previous steps.

Setup

To enable the step validation, configure the isValid option of the steps that should be validated. It accepts both boolean and StepPredicateFn parameters.

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

@Component({
    selector: 'my-app',
    template: `
        <div style="display: grid; grid-template-rows: repeat(3, 110px);">
            <kendo-stepper
                [steps]="steps"
                [(currentStep)]="currentStep"
                [style.width.px]="570">
            </kendo-stepper>

            <kendo-stepper
                [steps]="steps"
                [stepType]="'label'"
                [(currentStep)]="currentStep"
                [style.width.px]="570">
            </kendo-stepper>

            <kendo-stepper
                [steps]="stepsIcons"
                [stepType]="'full'"
                [(currentStep)]="currentStep"
                [style.width.px]="570">
            </kendo-stepper>
        </div>
    `
})
export class AppComponent {
    public currentStep = 1;

    public steps = [
        { label: 'Personal Info', isValid: true },
        { label: 'Education', isValid: false },
        { label: 'Experience', isValid: true },
        { label: 'Attachments', isValid: true, optional: true }
    ];

    public stepsIcons = [
        { label: 'Personal Info', icon: 'user', isValid: true },
        { label: 'Education', icon: 'dictionary-add', isValid: false },
        { label: 'Experience', icon: 'flip-vertical', isValid: true },
        { label: 'Attachments', icon: 'attachment', isValid: true, optional : true }
    ];
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { LayoutModule } from '@progress/kendo-angular-layout';
import { AppComponent } from './app.component';
@NgModule({
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        LayoutModule
    ],
    declarations: [ AppComponent ],
    bootstrap:    [ AppComponent ]
})
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);

Validation Logic

The Stepper enables you to specify custom validation logic for each step by providing a StepPredicateFn function for the isValid property of the step. This functionality is useful for scenarios where the validity of the step should correspond to the state of some external content, for example a form.

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

@Component({
    selector: 'my-app',
    template: `
            <kendo-stepper
                [steps]="steps"
                [stepType]="'full'"
                [(currentStep)]="currentStep"
                [style.width.px]="570">
            </kendo-stepper>
    `
})
export class AppComponent {
    public currentStep = 2;

    public steps = [
        { label: 'Personal Info', isValid: this.isStepValid },
        { label: 'Education', isValid: this.isStepValid },
        { label: 'Experience', isValid: this.isStepValid },
        { label: 'Attachments', isValid: this.isStepValid, optional: true }
    ];

    public isStepValid(index: number): boolean {
        return index % 2 === 0;
    }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { LayoutModule } from '@progress/kendo-angular-layout';
import { AppComponent } from './app.component';
@NgModule({
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        LayoutModule
    ],
    declarations: [ AppComponent ],
    bootstrap:    [ AppComponent ]
})
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);

Controlling the Validation

By default the Stepper validates only previous steps (whose index is less than the index of the current step). This behavior can be overridden by using the validate option of the steps. It accepts both boolean and StepPredicateFn parameters and allows you to have full control over when and which steps to validate.

If provided, a step will only be validated when its validate option is true. This allows handling specific scenarios, such as - validating certain steps only when a specific step is reached; or validating all steps when the last step is reached; or even forcing the validation for future steps (that were previously visited by the user).

/* tslint:disable */
import { Component } from '@angular/core';

@Component({
    selector: 'my-app',
    template: `
            <h5 style="margin-bottom: 20px;">The step validation will be triggered when the last step is reached</h5>
            <kendo-stepper
                [steps]="steps"
                [stepType]="'full'"
                [linear]="false"
                [(currentStep)]="currentStep"
                [style.width.px]="570">
            </kendo-stepper>
    `
})
export class AppComponent {
    public currentStep = 1;
    
    // Use an arrow function to capture the 'this' execution context of the class.
    public shouldValidate = (): boolean => {
        return this.currentStep === this.steps.length - 1;
    }

    public steps = [
        { label: 'Personal Info', isValid: this.isStepValid, validate: this.shouldValidate },
        { label: 'Education', isValid: this.isStepValid, validate: this.shouldValidate },
        { label: 'Experience', isValid: this.isStepValid, validate: this.shouldValidate },
        { label: 'Attachments', isValid: this.isStepValid, validate: this.shouldValidate, optional: true }
    ];

    public isStepValid(index: number): boolean {
        return index % 2 === 0;
    }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { LayoutModule } from '@progress/kendo-angular-layout';
import { AppComponent } from './app.component';
@NgModule({
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        LayoutModule
    ],
    declarations: [ AppComponent ],
    bootstrap:    [ AppComponent ]
})
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);

Triggering the Validation

As an addition to the validate option of the steps, the Stepper allows you to manually trigger the validation of the steps at any moment. To achieve this, invoke the validateSteps method of the component.

Steps that have their validate property set to false, will not be validated.

/* tslint:disable */
import { Component } from '@angular/core';
import { StepperComponent, StepperActivateEvent } from '@progress/kendo-angular-layout';

@Component({
    selector: 'my-app',
    template: `
            <button class='k-button' [style.margin.px]="20"
                    (click)="validateSteps(stepper)">
                Validate the current step
            </button>
            <kendo-stepper
                #stepper
                [steps]="steps"
                [stepType]="'full'"
                [linear]="false"
                [(currentStep)]="currentStep"
                [style.width.px]="570">
            </kendo-stepper>
    `
})
export class AppComponent {
    public currentStep = 0;
    public validatedSteps = [];

    public shouldValidate = (stepIdx: number): boolean => {
        return this.validatedSteps.indexOf(stepIdx) >= 0;
    }

    public steps = [
        { label: 'Personal Info', isValid: this.isStepValid, validate: this.shouldValidate },
        { label: 'Education', isValid: this.isStepValid, validate: this.shouldValidate },
        { label: 'Experience', isValid: this.isStepValid, validate: this.shouldValidate  },
        { label: 'Attachments', isValid: this.isStepValid, validate: this.shouldValidate, optional: true }
    ];

    public isStepValid(index: number): boolean {
        return index % 2 === 0;
    }

    public validateSteps(stepper: StepperComponent): void {
        this.validatedSteps.push(this.currentStep);

        stepper.validateSteps();
    }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { LayoutModule } from '@progress/kendo-angular-layout';
import { AppComponent } from './app.component';
@NgModule({
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        LayoutModule
    ],
    declarations: [ AppComponent ],
    bootstrap:    [ AppComponent ]
})
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);

Custom Validation Icons

The Stepper allows you to customize the rendered validation icons. To achieve this specify the successIcon and errorIcon properties of the Stepper and provide the CSS classes that should be applied to the icons.

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

@Component({
    selector: 'my-app',
    template: `
            <kendo-stepper
                [steps]="steps"
                [stepType]="'full'"
                [(currentStep)]="currentStep"
                [successIcon]="'k-icon k-i-check-circle'"
                [errorIcon]="'k-icon k-i-close-outline'"
                [style.width.px]="570">
            </kendo-stepper>
    `
})
export class AppComponent {
    public currentStep = 1;

    public steps = [
        { label: 'Personal Info', isValid: true },
        { label: 'Education', isValid: false },
        { label: 'Experience', isValid: true },
        { label: 'Attachments', isValid: true, optional: true }
    ];
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { LayoutModule } from '@progress/kendo-angular-layout';
import { AppComponent } from './app.component';
@NgModule({
    imports: [
        BrowserModule,
        BrowserAnimationsModule,
        LayoutModule
    ],
    declarations: [ AppComponent ],
    bootstrap:    [ AppComponent ]
})
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