Angular Stepper - Getting Started
jQuery
Angular
Vue
React
Stepper is a UI component that allows users to navigate multi-step forms and processes such as checkouts, set-up wizards, and sign-up forms.
This tutorial guides you through the following steps:
- Add a Stepper to a page.
- Configure the component's core settings.
- Create six steps and specify their icons, labels, and other options.
- Disable completed steps as a user progresses.
Each section in this tutorial covers a single configuration step. You can find the complete source code in the following GitHub repository:
Create Stepper
jQuery
Add DevExtreme to your jQuery application and use the code below to create a Stepper component with one step. This example utilizes the items[] array, but you can use dataSource to define steps as well. If you do not specify at least one step, Stepper does not display any data.
$(function() {
$("#stepper").dxStepper({
items: [
{}
]
});
});
<html>
<head>
<!-- ... -->
<script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/devextreme@25.2-next/dist/css/dx.light.css">
<script type="text/javascript" src="https://unpkg.com/devextreme@25.2-next/dist/js/dx.all.js"></script>
<script type="text/javascript" src="index.js"></script>
</head>
<body>
<div id="stepper"></div>
</body>
</html>Angular
Add DevExtreme to your Angular application and use the code below to create a Stepper component with one step. This example utilizes the items[] array, but you can use dataSource to define steps as well. If you do not specify at least one step, Stepper will display no data.
<dx-stepper
[items]="steps">
</dx-stepper>
import { Component } from '@angular/core';
import { DxStepperTypes } from 'devextreme-angular/ui/stepper';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
steps: DxStepperTypes.Item[] = [
{}
]
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { DxStepperModule } from 'devextreme-angular';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
DxStepperModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }Vue
Add DevExtreme to your Vue application and use the code below to create a Stepper component with one step. This example utilizes the items[] array, but you can use dataSource to define steps as well. If you do not specify at least one step, Stepper will display no data.
<script setup lang="ts">
import { reactive } from 'vue';
import { DxStepper, DxItem, DxStepperTypes } from 'devextreme-vue/stepper';
import 'devextreme/dist/css/dx.light.css';
const items: DxStepperTypes.Item[] = reactive([
{}
]);
</script>
<template>
<DxStepper ref="stepperRef">
<DxItem
v-for="(item, index) in items"
:key="index"
/>
</DxStepper>
</template>React
Add DevExtreme to your React application and use the code below to create a Stepper component with one step. This example utilizes the items[] array, but you can use dataSource to define steps as well. If you do not specify at least one step, Stepper will display no data.
import React, { JSX, useState } from 'react';
import { Stepper, Item, StepperTypes } from 'devextreme-react/stepper';
import 'devextreme/dist/css/dx.light.css';
export default function App(): JSX.Element {
const [steps, setSteps] = useState<any[]>([
{}
]);
return (
<Stepper>
{
steps.map((item, index) => (
<Item key={index} {...item} />
))
}
</Stepper>
);
}Configure Steps
This tutorial specifies the following properties to configure Stepper steps:
- label
Assigns a step label. - icon
Defines a step icon. For more information on the DevExteme icon library, refer to DevExtreme Icons. - optional
Adds an "Optional" caption.
You can also specify the following properties:
- isValid
Indicates input validation state for a step. - text
Defines text displayed on a step indicator. - hint
Specifies step hint text that appears upon hover or long-press. - disabled
Disables a step.
The code below assigns six steps to the component with different configuration options.
jQuery
$(function() {
$("#stepper").dxStepper({
items: [{
label: 'Personal Details'
}, {
label: 'Program Selection',
icon: 'detailslayout'
}, {
label: 'Campus and Start Dates',
icon: 'map'
}, {
label: 'Supporting Documents',
icon: 'textdocument'
}, {
label: 'Scholarship and Aid',
icon: 'money',
optional: true
}, {
label: 'Review and Submit',
icon: 'send'
}]
});
});Angular
// ...
@Component({
// ...
})
export class AppComponent {
steps: DxStepperTypes.Item[] = [
{ label: 'Personal Details' },
{ label: 'Program Selection', icon: 'detailslayout' },
{ label: 'Campus and Start Dates', icon: 'map' },
{ label: 'Supporting Documents', icon: 'textdocument' },
{ label: 'Scholarship and Aid', icon: 'money', optional: true },
{ label: 'Review and Submit', icon: 'send' }
];
}Vue
<script setup lang="ts">
// ...
const items: DxStepperTypes.Item[] = reactive([
{ label: 'Personal Details' },
{ label: 'Program Selection', icon: 'detailslayout' },
{ label: 'Campus and Start Dates', icon: 'map' },
{ label: 'Supporting Documents', icon: 'textdocument' },
{ label: 'Scholarship and Aid', icon: 'money', optional: true },
{ label: 'Review and Submit', icon: 'send' }
]);
</script>
<template>
// ...
</template>React
// ...
export default function App(): JSX.Element {
const [steps, setSteps] = useState<any[]>([
{ label: 'Personal Details' },
{ label: 'Program Selection', icon: 'detailslayout' },
{ label: 'Campus and Start Dates', icon: 'map' },
{ label: 'Supporting Documents', icon: 'textdocument' },
{ label: 'Scholarship and Aid', icon: 'money', optional: true },
{ label: 'Review and Submit', icon: 'send' },
]);
return (
// ...
);
}Customize Steps
Specify items[].template to customize an individual step, or itemTemplate to customize all steps in the component. This tutorial replaces the first step indicator with a star.
For instructions on how to define item templates, refer to Object Structures - template.
jQuery
$(function() {
$("#stepper").dxStepper({
items: [{
label: 'Personal Details',
template: (data) => `
<div class='star dx-step-indicator'></div>
<div class='dx-step-caption'>
<div class='dx-step-label'>${data.label}</div>
</div>
`,
},
// ...
]
});
});
.star {
aspect-ratio: 1;
clip-path: polygon(50% 0,79% 90%,2% 35%,98% 35%,21% 90%);
box-shadow: 0 0 0 8px #fafafa;
}Angular
<dx-stepper
[items]="steps"
>
<div *dxTemplate="let data of 'starTemplate'">
<div class="star dx-step-indicator"></div>
<div class="dx-step-caption">
<div class="dx-step-label">{{ data.label }}</div>
</div>
</div>
</dx-stepper>
// ...
@Component({
// ...
})
export class AppComponent {
steps: DxStepperTypes.Item[] = [
{ label: 'Personal Details', template: 'starTemplate' },
// ...
];
}
.star {
aspect-ratio: 1;
clip-path: polygon(50% 0,79% 90%,2% 35%,98% 35%,21% 90%);
box-shadow: 0 0 0 8px #fafafa;
}Vue
<script setup lang="ts">
// ...
const items: DxStepperTypes.Item[] = reactive([
{ label: 'Personal Details', template: 'star' },
// ...
]);
</script>
<template>
<DxStepper ref="stepperRef" @selection-changed="onSelectionChanged">
<DxItem
v-for="(item, index) in items"
:key="index"
v-bind="item"
:template="item.template"
/>
<template #star="{ data }">
<div class="star dx-step-indicator"></div>
<div class="dx-step-caption">
<div class="dx-step-label">{{ data.label }}</div>
</div>
</template>
</DxStepper>
</template>
<style>
.star {
aspect-ratio: 1;
clip-path: polygon(50% 0,79% 90%,2% 35%,98% 35%,21% 90%);
box-shadow: 0 0 0 8px #fafafa;
}
</style>React
// ...
export default function App(): JSX.Element {
function renderStarTemplate(data: StepperTypes.Item): JSX.Element {
return (
<React.Fragment>
<div className="star dx-step-indicator"></div>
<div className="dx-step-caption">
<div className="dx-step-label">{data.label}</div>
</div>
</React.Fragment>
);
}
const [steps, setSteps] = useState<any[]>([
{ label: 'Personal Details', render: renderStarTemplate },
// ...
]);
return (
// ...
);
}
.star {
aspect-ratio: 1;
clip-path: polygon(50% 0,79% 90%,2% 35%,98% 35%,21% 90%);
box-shadow: 0 0 0 8px #fafafa;
}Configure Selection
The following Stepper properties allow you to configure selection at runtime:
- onSelectionChanged
A function that is called after selection has changed. - onSelectionChanging
A function that is called before selection changes. - selectedIndex
The selected item index. - selectedItem
The selected item object.
This tutorial uses onSelectionChanged to disable steps as users move through the component.
jQuery
$(function() {
$("#stepper").dxStepper({
// ...
onSelectionChanged: ({ component, addedItems }) => {
const items = component.option("items");
const newIndex = items.findIndex(item => addedItems[0].label === item.label);
component.option(`items[${newIndex - 1}].disabled`, true);
},
});
});Angular
<dx-stepper
[items]="steps"
(onSelectionChanged)="onSelectionChanged($event)">
// ...
</dx-stepper>
// ...
@Component({
// ...
})
export class AppComponent {
onSelectionChanged(e: DxStepperTypes.SelectionChangedEvent): void {
const newItem = e.addedItems[0];
const newIndex = this.steps.findIndex(item => item.label === newItem.label);
if (newIndex > 0 && !this.steps[newIndex - 1].disabled) {
this.steps[newIndex - 1].disabled = true;
}
}
}Vue
<script setup lang="ts">
// ...
const onSelectionChanged = (e: DxStepperTypes.SelectionChangedEvent) => {
const newItem = e.addedItems[0];
const newIndex = items.findIndex((item) => item.label === newItem.label);
if (newIndex > 0) {
items[newIndex - 1].disabled = true;
}
};
</script>
<template>
<DxStepper ref="stepperRef" @selection-changed="onSelectionChanged">
<!-- ... -->
</DxStepper>
</template>React
// ...
export default function App(): JSX.Element {
// ...
function onSelectionChanged(e: StepperTypes.SelectionChangedEvent): void {
const newItem = e.addedItems[0];
const newIndex = steps.findIndex((item) => item.label === newItem.label);
if (newIndex > 0 && !steps[newIndex - 1].disabled) {
const updated = [...steps];
updated[newIndex - 1] = { ...updated[newIndex - 1], disabled: true };
setSteps(updated);
}
}
return (
<Stepper onSelectionChanged={onSelectionChanged}>
// ...
</Stepper>
);
}If you have technical questions, please create a support ticket in the DevExpress Support Center.