DevExtreme Angular - First Steps

Angular
NOTE
You should be familiar with the basic concepts and patterns of Angular to use DevExtreme components. If you are not, refer to the Angular documentation and follow the getting-started tutorial first.
Vue
NOTE
You should be familiar with the basic concepts and patterns of Angular to use DevExtreme components. If you are not, refer to the Angular documentation and follow the getting-started tutorial first.
React
NOTE
You should be familiar with the basic concepts and patterns of Angular to use DevExtreme components. If you are not, refer to the Angular documentation and follow the getting-started tutorial first.

In this step-by-step tutorial, you will build a simple task list application with a progress bar. By the end, you will have the following application:

The application includes two DevExtreme components: DataGrid and ProgressBar. The DataGrid displays tasks, and you can mark them as complete or incomplete. The ProgressBar above the DataGrid indicates task completion progress.

You can find the full source code in the GitHub repository:

View on GitHub

Setup Your Project

jQuery

Create an empty web application. Then add jQuery and DevExtreme source files to the <head>:

index.html
<head>
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script type="text/javascript" src="https://cdn3.devexpress.com/jslib/minor_25_1/js/dx.all.js"></script>
</head>

For complete installation instructions, refer to the following help topic: Add DevExtreme to a jQuery Application.

Angular

Create an empty Angular application (see Angular Documentation: Set up a new project locally). Run the following commands:

npm install -g @angular/cli
ng new first-steps-project

Then, in the project file directory, run the following DevExtreme CLI command to add DevExtreme to your app:

npx -p devextreme-cli devextreme add devextreme-angular

For complete installation instructions, refer to the following help topic: Add DevExtreme to an Angular CLI Application.

NOTE
To start with an application that contains predefined components, try CLI-based DevExtreme Application Template. This template includes a navigation menu and several sample views in a responsive layout.
Vue

Create an empty Vue JavaScript application (see Vue Documentation: Creating a Vue Application). Run the following command:

npm create vue@latest

Then, in the project file directory, run the following DevExtreme CLI command to add DevExtreme to your app:

npx -p devextreme-cli devextreme add devextreme-vue

For complete installation instructions, refer to the following help topic: Add DevExtreme to a Vue Application.

NOTE
To start with an application that contains predefined components, try CLI-based DevExtreme Application Template. This template includes a navigation menu and several sample views in a responsive layout.
React

Create an empty React JavaScript application (see React Documentation: Build a React app from Scratch). For instance, to create an application with Vite, run the following command:

npm create vite@latest my-app -- --template react

Then, in the project file directory, run the following DevExtreme CLI command to add DevExtreme to your app:

npx -p devextreme-cli devextreme add devextreme-react

For complete installation instructions, refer to the following help topic: Add DevExtreme to a React Application.

NOTE
To start with an application that contains predefined components, try CLI-based DevExtreme Application Template. This template includes a navigation menu and several sample views in a responsive layout.

Style the App

DevExtreme offers over 40 predefined themes for component styling. You can also create a custom theme with our ThemeBuilder.

In the next step of the tutorial, apply the dx.light theme and add CSS styles to the components.

jQuery

To apply a theme, link its file in the <head> between jQuery and DevExtreme sources (the order is important):

index.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/minor_25_1/css/dx.light.css" />
    <link rel="stylesheet" type="text/css" href="index.css" />
    <script type="text/javascript" src="https://cdn3.devexpress.com/jslib/minor_25_1/js/dx.all.js"></script>
</head>
Angular

To apply a theme, open the angular.json file and reference a stylesheet:

angular.json
{
  "projects": {
    "ProjectName": {
      "architect": {
        "build": {
          "options": {
            "styles": [
              "node_modules/devextreme/dist/css/dx.light.css",
              "src/styles.css"
            ],
            ...
          },
          ...
        },
        ...
      }
    },
    ...
  },
  ...
}
Vue

To apply a theme, import a stylesheet where DevExtreme components are used or in the main application file:

import 'devextreme/dist/css/dx.light.css';
React

To apply a theme, import a stylesheet where DevExtreme components are used or in the main application file:

import 'devextreme/dist/css/dx.light.css';

If you want to apply theme colors and typography settings to all page elements (and not only to DevExtreme UI components), add a dx-viewport class to the <body> tag of your application's index.html file.

To configure component styles manually, create an index.css file and import it alongside the DevExtreme theme CSS file:

index.css
#dashboard {
    display: grid;
    gap: 20px;
    max-width: 900px;
    margin: 40px auto;
    padding: 20px;
    box-sizing: border-box;
}

#progress,
#task-grid {
    background: #fff;
    padding: 16px;
    border-radius: 8px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}

Specify the Page Layout

jQuery

Next, specify the component layout in the HTML file:

index.html
<div id="dashboard">
    <div id="progress"></div>
    <div id="task-grid"></div>
</div>

The dashboard is the container for two components: ProgressBar and DataGrid.

Angular

Next, import components into app.component.ts:

app.component.ts
import { Component } from '@angular/core';
import { DxDataGridComponent } from 'devextreme-angular/ui/data-grid';
import { DxProgressBarComponent } from 'devextreme-angular/ui/progress-bar';

@Component({
    selector: 'app-root',
    standalone: true,
    imports: [DxDataGridComponent, DxProgressBarComponent],
    templateUrl: './app.component.html',
    styleUrl: './app.component.css'
})
export class AppComponent { }

Specify the component layout in the HTML file:

app.component.html
<div id="dashboard">
    <dx-progress-bar id="progress"></dx-progress-bar>
    <dx-data-grid id="task-grid"></dx-data-grid>
</div>

The dashboard is the container for two components: ProgressBar and DataGrid.

For detailed instructions on imports, refer to the Import DevExtreme Components help topic.

Vue

Next, import components and specify their layout:

App.vue
<template>
    <div id="dashboard">
        <DxProgressBar id="progress" />
        <DxDataGrid id="task-grid"></DxDataGrid>
    </div>
</template>
<script setup lang="ts">
import DxProgressBar from 'devextreme-vue/progress-bar';
import DxDataGrid from 'devextreme-vue/data-grid';
</script>

The dashboard is the container for two components: ProgressBar and DataGrid.

For detailed instructions on imports, refer to the Import DevExtreme Components help topic.

React

Next, import components and specify their layout:

App.tsx
import DataGrid from 'devextreme-react/data-grid';
import ProgressBar from 'devextreme-react/progress-bar';

function App(): JSX.Element {
    return(
        <div id="dashboard">
            <ProgressBar id="progress" />
            <DataGrid id="task-grid"></DataGrid>
        </div>
    );
}

export default App;

The dashboard is the container for two components: ProgressBar and DataGrid.

For detailed instructions on imports, refer to the Import DevExtreme Components help topic.

Configure DataGrid

Now, you will create a DataGrid and configure its main functionality.

Bind DataGrid to Data

The DataGrid component can load and update data from different data source types. In this guide, a small local array serves as the data source. Follow these steps:

jQuery
  1. Create the tasks array.
  2. Assign the array to the dataSource property.
  3. Specify keyExpr (id in this case).
  4. In the columns array, define which columns you want to display.

    index.js
    $(() => {
        const tasks = [
            { id: 1, task: "Buy groceries", dueDate: new Date(), done: false },
            { id: 2, task: "Write a blog post", dueDate: new Date(), done: true }
        ];
        $("#task-grid").dxDataGrid({
            dataSource: tasks,
            keyExpr: "id",
            columns: ["task", "dueDate", "done"],
        });
    });
Angular
  1. Create the tasks array.

    app.component.ts
    export class AppComponent {
        tasks = [
            { id: 1, task: "Buy groceries", dueDate: new Date(), done: false },
            { id: 2, task: "Write a blog post", dueDate: new Date(), done: true }
        ];
    }
  2. Assign the array to the dataSource property.

  3. Specify keyExpr (id in this case).
  4. Use the nested dxi-data-grid-column configuration component to define columns you want to display.

    app.component.html
    <dx-data-grid
        id="task-grid"
        [dataSource]="tasks"
        keyExpr="id"
    >
        <dxi-data-grid-column dataField="task"></dxi-data-grid-column>
        <dxi-data-grid-column dataField="dueDate"></dxi-data-grid-column>
        <dxi-data-grid-column dataField="done"></dxi-data-grid-column>
    </dx-data-grid>
  5. Remember to import the DxiDataGridColumnComponent component.

    app.component.ts
    import { Component } from '@angular/core';
    import { DxDataGridComponent, DxiDataGridColumnComponent } from 'devextreme-angular/ui/data-grid';
    @Component({
        selector: 'app-root',
        standalone: true,
        imports: [DxDataGridComponent, DxiDataGridColumnComponent],
        templateUrl: './app.component.html',
        styleUrl: './app.component.css'
    })
    export class AppComponent { ... }

For more information about the nested configuration components, refer to the following help topics:

Vue
  1. Create the tasks array.
  2. Assign the array to the dataSource property.
  3. Specify keyExpr (id in this case).
  4. Use the nested DxColumn configuration component to define columns you want to display. Remember to import the necessary configuration components.

    App.vue
    <template>
        <div id="dashboard">
            <DxProgressBar id="progress" />
            <DxDataGrid
                id="task-grid"
                :data-source="tasks"
                key-expr="id"
            >
                <DxColumn data-field="task" />
                <DxColumn data-field="dueDate" />
                <DxColumn data-field="done" />
            </DxDataGrid>
        </div>
    </template>
    <script setup lang="ts">
    import DxDataGrid, { DxColumn } from 'devextreme-vue/data-grid';
    
    const tasks = [
        { id: 1, task: "Buy groceries", dueDate: new Date(), done: false },
        { id: 2, task: "Write a blog post", dueDate: new Date(), done: true }
    ];
    </script>

For more information about the nested configuration components, refer to the following help topics:

React
  1. Create the tasks array.
  2. Assign the array to the dataSource property.
  3. Specify keyExpr (id in this case).
  4. Use the nested Column configuration component to define columns you want to display. Remember to import the necessary configuration components.

    App.tsx
    import DataGrid, { Column } from 'devextreme-react/data-grid';
    
    const tasks = [
        { id: 1, task: "Buy groceries", dueDate: new Date(), done: false },
        { id: 2, task: "Write a blog post", dueDate: new Date(), done: true }
    ];
    
    function App(): JSX.Element {
        return(
            <div id="dashboard">
                <ProgressBar id="progress" />
                <DataGrid
                    id="task-grid" 
                    dataSource={tasks}
                    keyExpr="id"
                >
                    <Column dataField="task" />
                    <Column dataField="dueDate" />
                    <Column dataField="done" />
                </DataGrid>
            </div>
        );
    }
    
    export default App;

For more information about the nested configuration components, refer to the following help topics:

Configure Editing

The DataGrid component allows you to configure core features such as sorting, filtering, search, grouping, selection, and editing. Enable editing to allow users to add, edit, and delete rows.

This guide explains how to create a task list where users can check off tasks, remove them, and add new ones. To do this, specify the following editing options:

  • allowAdding
    Set to true - allows users to add new rows.

  • allowDeleting
    Set to true - allows users to remove rows.

  • allowUpdating
    Set to true - allows users to update rows.

  • mode
    Change the mode from the default "row" to "cell" for easy task status changes.

  • newRowPosition
    Set new rows to appear at the "last" position for a top-to-bottom task list.

jQuery
index.js
$(() => {
    $("#task-grid").dxDataGrid({
        dataSource: tasks,
        keyExpr: "id",
        columns: ["task", "dueDate", "done"],
        editing: {
            mode: "cell",
            allowUpdating: true,
            allowAdding: true,
            allowDeleting: true,
            newRowPosition: "last"
        },
    });
});
Angular
app.component.html
<dx-data-grid
    id="task-grid"
    [dataSource]="tasks"
    keyExpr="id"
>
    <dxo-data-grid-editing 
        mode="row" 
        [allowUpdating]="true" 
        [allowDeleting]="true" 
        [allowAdding]="true"
        newRowPosition="last"
    ></dxo-data-grid-editing>
</dx-data-grid>

Remember to import the DxoDataGridEditingComponent component:

app.component.ts
import { Component } from '@angular/core';
import { DxDataGridComponent, DxiDataGridColumnComponent, DxoDataGridEditingComponent } from 'devextreme-angular/ui/data-grid';
@Component({
    selector: 'app-root',
    standalone: true,
    imports: [DxDataGridComponent, DxiDataGridColumnComponent, DxoDataGridEditingComponent],
    templateUrl: './app.component.html',
    styleUrl: './app.component.css'
})
export class AppComponent { ... }
Vue
App.vue
<template>
    <div id="dashboard">
        <DxProgressBar id="progress" />
        <DxDataGrid
            id="task-grid"
            :data-source="tasks"
            key-expr="id"
        >
            <DxEditing 
                mode="row"
                :allow-updating="true"
                :allow-adding="true"
                :allow-deleting="true"
                new-row-position="last"
            />
        </DxDataGrid>
    </div>
</template>
<script setup lang="ts">
import DxDataGrid, { DxColumn, DxEditing } from 'devextreme-vue/data-grid';
// ...
</script>
React
App.tsx
import DataGrid, { Column, Editing } from 'devextreme-react/data-grid';
// ...

function App(): JSX.Element {
    return(
        <div id="dashboard">
            <ProgressBar id="progress" />
            <DataGrid
                id="task-grid" 
                dataSource={tasks}
                keyExpr="id"
            >
                <Editing 
                    mode="row"
                    allowUpdating={true}
                    allowAdding={true}
                    allowDeleting={true}
                    newRowPosition="last"
                />
            </DataGrid>
        </div>
    );
}

export default App;

Show Progress

At this point of the tutorial, you have created a DataGrid that stores task records and allows users to edit them. To display task progress, you integrated a ProgressBar into the layout. The next steps are to configure the ProgressBar options and synchronize it with DataGrid updates.

Configure ProgressBar

jQuery

First, create a ProgressBar and save its instance to access its methods later.

Next, set the value option to 50, as half of the tasks in the initial list are completed.

index.js
$(() => {
    const progress = $("#progress").dxProgressBar({
        value: 50,
    }).dxProgressBar("instance");
});
Angular

Create a progressValue variable and set it to 50, as half of the tasks in the initial list are completed.

app.component.ts
export class AppComponent {
    // ...
    progressValue = 50;
}

Then, bind the value option to this variable. Directly assigning 50 will not work, as the variable will synchronize ProgressBar and DataGrid later.

app.component.html
<dx-progress-bar ...
    [value]="progressValue"
>
</dx-progress-bar>
Vue

Create a progressValue variable and set its ref to 50, as half of the tasks in the initial list are completed. Then, bind the value option to this variable. Directly assigning 50 will not work, as the variable will synchronize ProgressBar and DataGrid later.

App.vue
<template>
    <div id="dashboard">
        <DxProgressBar ... 
            :value="progressValue"
        />
        <DxDataGrid ... ></DxDataGrid>
    </div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import DxProgressBar from 'devextreme-vue/progress-bar';
//...

const progressValue = ref(50);
</script>
React

Manage the progress bar state with React useState Hook. Set the Hook initial value to 50, as half of the tasks in the initial list are completed. Bind the value option to the progressValue variable. setProgressValue keeps ProgressBar and DataGrid synchronized.

App.tsx
import { useState } from 'react';
import ProgressBar from 'devextreme-react/progress-bar';

function App(): JSX.Element {
    const [progressValue, setProgressValue] = useState(50);
    return(
        <div id="dashboard">
            <ProgressBar 
                value={progressValue}
            />
            <DataGrid ... ></DataGrid>
        </div>
    );
}

export default App;

Sync ProgressBar with DataGrid

jQuery

To synchronize ProgressBar with DataGrid, define an updateProgress function. This function checks completed tasks and updates the ProgressBar value using the option method. Use this function to handle the following events: onRowUpdated, onRowInserted, and onRowRemoved.

index.js
$(() => {
    $("#task-grid").dxDataGrid({
        // ...
        onRowUpdated: updateProgress,
        onRowInserted: updateProgress,
        onRowRemoved: updateProgress
    });

    function updateProgress() {
        const all = tasks.length;
        const completed = tasks.filter((t) => t.done).length;
        progress.option("value", Math.round((completed / all) * 100));
    }
});
Angular

To synchronize ProgressBar with DataGrid, define an updateProgress function. This function checks completed tasks and updates the ProgressBar value using the progressValue variable.

app.component.ts
export class AppComponent {
    // ...
    updateProgress() {
        const all = this.tasks.length;
        const completed = this.tasks.filter((t) => t.done).length;
        this.progressValue = Math.round((completed / all) * 100);
    };
}

Use this function to handle the following DataGrid events: onRowUpdated, onRowInserted, and onRowRemoved.

app.component.html
<dx-data-grid ...
    (onRowUpdated)="updateProgress($event)"
    (onRowInserted)="updateProgress($event)"
    (onRowRemoved)="updateProgress($event)"
></dx-data-grid>
Vue

To synchronize ProgressBar with DataGrid, define an updateProgress function. This function checks completed tasks and updates the ProgressBar value using the progressValue variable. Use this function to handle the following DataGrid events: onRowUpdated, onRowInserted, and onRowRemoved.

App.vue
    <template>
        <div id="dashboard">
            <DxProgressBar ... />
            <DxDataGrid ...
                @row-updated="updateProgress"
                @row-inserted="updateProgress"
                @row-removed="updateProgress"
            >
            </DxDataGrid>
        </div>
    </template>
    <script setup lang="ts">
    //...
    function updateProgress() {
        const all = tasks.length;
        const completed = tasks.filter((t) => t.done).length;
        progressValue.value = Math.round((completed / all) * 100);
    };
    </script>
React

To synchronize ProgressBar with DataGrid, define an updateProgress function. This function checks completed tasks and updates the ProgressBar value using the progressValue variable. Use this function to handle the following DataGrid events: onRowUpdated, onRowInserted, and onRowRemoved.

App.tsx
function App(): JSX.Element {
    const [progressValue, setProgressValue] = useState(50);
    function updateProgress() {
        const all = tasks.length;
        const completed = tasks.filter((t) => t.done).length;
        setProgressValue(Math.round((completed / all) * 100));
    };
    return(
        <div id="dashboard">
            <ProgressBar ... />
            <DataGrid ...
                onRowUpdated={updateProgress}
                onRowInserted={updateProgress}
                onRowRemoved={updateProgress}
            >
            </DataGrid>
        </div>
    );
}

export default App;

You can find the full source code in the GitHub repository:

View on GitHub

Explore More

To learn more about DevExtreme, refer to the following sources:

jQuery
  1. Learn the basics with Component Configuration Syntax.

  2. Edit and copy code from over 450 DevExtreme demos.

  3. To learn more about a specific component, review guides and API references in the documentation. For common issues, refer to the following resources:

  4. Need help? Submit a ticket to the DevExpress Support Center.

Angular
  1. Learn the basics with Component Configuration Syntax.

  2. Edit and copy code from over 450 DevExtreme demos or our UI Template Gallery.

  3. To learn more about a specific component, review guides and API references in the documentation. For common issues, refer to the following resources:

  4. Need help? Submit a ticket to the DevExpress Support Center.

Vue
  1. Learn the basics with Component Configuration Syntax.

  2. Edit and copy code from over 450 DevExtreme demos or our UI Template Gallery.

  3. To learn more about a specific component, review guides and API references in the documentation. For common issues, refer to the following resources:

  4. Need help? Submit a ticket to the DevExpress Support Center.

React
  1. Learn the basics of Component Configuration Syntax.

  2. Edit and copy code from over 450 DevExtreme demos or our UI Template Gallery.

  3. To learn more about a specific component, review guides and API references in the documentation. For common issues, refer to the following resources:

  4. Need help? Submit a ticket to the DevExpress Support Center.