JavaScript/jQuery 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://cdn3.devexpress.com/jslib/25.1.3/css/dx.light.css"> <script type="text/javascript" src="https://cdn3.devexpress.com/jslib/25.1.3/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.