JavaScript/jQuery Drawer - Getting Started

jQuery
NOTE
Before you start the tutorial, ensure DevExtreme is installed in your application.
Angular
NOTE
Before you start the tutorial, ensure DevExtreme is installed in your application.
Vue
NOTE
Before you start the tutorial, ensure DevExtreme is installed in your application.
React
NOTE
Before you start the tutorial, ensure DevExtreme is installed in your application.

The Drawer is a dismissible or permanently visible panel used for navigation in responsive web application layouts.

jQuery

This tutorial shows how to create a Drawer that allows a user to switch between pages. The Drawer is opened and closed via a button on a toolbar.

Angular

DevExtreme supplies an application template that implements a responsive layout using the Drawer. You can use the template instead of following this tutorial.

If the template is unsuitable, follow the instructions below to create a Drawer that allows a user to switch between pages. The Drawer is opened and closed via a button on a toolbar.

Vue

DevExtreme supplies an application template that implements a responsive layout using the Drawer. You can use the template instead of following this tutorial.

If the template is unsuitable, follow the instructions below to create a Drawer that allows a user to switch between pages. The Drawer is opened and closed via a button on a toolbar.

React

DevExtreme supplies an application template that implements a responsive layout using the Drawer. You can use the template instead of following this tutorial.

If the template is unsuitable, follow the instructions below to create a Drawer that allows a user to switch between pages. The Drawer is opened and closed via a button on a toolbar.

Refer to the sections below for details on each configuration step. You can also find the full code in the following GitHub repository: getting-started-with-drawer.

Create the Drawer

Wrap the view in the Drawer and specify a template for the Drawer's content. Inside the template, set the Drawer's width. You can use the nested UI component's width property for this (see Implement Navigation), but in this tutorial, we use the width CSS property. The Drawer's height adjusts to the view's height (specified via the height property).

In addition, you can specify the minSize property to make the Drawer partially visible in the closed state.

jQuery
index.html
index.js
index.css
<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/21.2.15/css/dx.light.css">
        <link rel="stylesheet" href="index.css">
        <script type="text/javascript" src="https://cdn3.devexpress.com/jslib/21.2.15/js/dx.all.js"></script>
        <script type="text/javascript" src="index.js"></script>
    </head>
    <body>
        <div id="drawer">
            <div id="view">View content</div>
        </div>
    </body>
</html>
$(function() {
    $("#drawer").dxDrawer({
        template: function(e) {
            return $("<div style='width: 150px'>Drawer content</div>");
        },
        height: 250,
        minSize: 37
    });
});
.dx-overlay-content {
    background-color: lightgray;
}
#view {
    margin-left: 10px;
    margin-top: 10px;
}
Angular
app.component.html
app.component.ts
app.module.ts
app.component.css
<dx-drawer
    template="template"
    [height]="250"
    [minSize]="37">
    <div *dxTemplate="let data of 'template'">
        <div style="width: 150px">Drawer content</div>
    </div>
    <div>View content</div>
</dx-drawer>
import { Component } from "@angular/core";

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})

export class AppComponent {

}
import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";
import { AppComponent } from "./app.component";

import { DxDrawerModule } from "devextreme-angular";

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        DxDrawerModule
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule { }
::ng-deep .dx-overlay-content {
    background-color: lightgray;
}
::ng-deep #view {
    margin-left: 10px;
    margin-top: 10px;
}
Vue
App.vue
<template>
    <div>
        <DxDrawer
            :minSize="37"
            :height="250"
            template="list">
            <template #list>
                <div style="width: 150px">Drawer content</div>
            </template>
            <div id="view">
                <div>View content</div>
            </div>
        </DxDrawer>
    </div>
</template>

<script>
import DxDrawer from 'devextreme-vue/drawer';

export default {
    components: {
        DxDrawer
    }
};
</script>

<style>
.dx-overlay-content {
    background-color: lightgray;
}
#view {
    margin-left: 10px;
    margin-top: 10px;
}
</style>
React
NavigationDrawer.js
NavigationDrawer.css
App.js
import React from "react";

import "devextreme/dist/css/dx.light.css";
import "./NavigationDrawer.css";

import { Drawer } from "devextreme-react/drawer";

class NavigationDrawer extends React.Component {
    constructor(props) {
        super(props);
    }
    render() {
        return (
            <React.Fragment>
                <Drawer
                    minSize={37}
                    height={250}
                    render={ () => <div style={{width: "150px"}}>Drawer content</div> } >
                    <div>View content</div>
                </Drawer>
            </React.Fragment>
        );
    }
}
export default NavigationDrawer;
.dx-overlay-content {
    background-color: lightgray;
}
#view {
    margin-left: 10px;
    margin-top: 10px;
}
import React, { Component } from "react";

import NavigationDrawer from "./components/NavigationDrawer";

class App extends Component {
    render() {
        return (
            <div className="App">
                <NavigationDrawer />
            </div>
        );
    }
}
export default App;
ASP.NET MVC Controls
_Layout.cshtml
Site.css
@(Html.DevExtreme().Drawer()
    .ID("layout-drawer")
    .Height(250)
    .MinSize(37)
    .Template(@<text><div style="width: 150px">Drawer content</div></text>)
    .Content(@<text><div id=".drawer-view-content">View content</div></text>)
)
.dx-overlay-content {
    background-color: lightgray;
}

.drawer-view-content {
    margin-left: 10px;
    margin-top: 10px;
}

If you run the code, you should see a partially visible Drawer and a view that displays View content.

NOTE
The Drawer UI component is not designed to contain another Drawer. Do not use nested Drawers to avoid possible issues in your application.

Open and Close the Drawer

Depending on the library or framework you use, call the toggle() method or bind the opened property to a component property.

In the following code, a toolbar button outside the Drawer opens and closes it:

jQuery
index.js
index.html
style.css
$(function() {
    const drawer = $("#drawer").dxDrawer({ 
        // ... 
    }).dxDrawer("instance");
    $("#toolbar").dxToolbar({
        items: [{
            widget: "dxButton",
            location: "before",
            options: {
                icon: "menu",
                onClick: function() {
                    drawer.toggle();
                }
            }
        }]
    });
})
<div id="toolbar"></div>
<div id="drawer">
    <div id="view">View content</div>
</div>
/* ... */
#toolbar {
    background-color: rgba(191, 191, 191, .15);
    padding: 5px 10px;
}
.dx-toolbar-button .dx-button {
    background-color: rgba(191, 191, 191, -0.15);
    border: none;
}
.dx-toolbar-button > .dx-toolbar-item-content {
    margin-left: -7px;
}
Angular
app.component.html
app.component.ts
app.module.ts
app.component.css
<dx-toolbar id="toolbar">
    <dxi-item 
        widget="dxButton"
        [options]="buttonOptions"
        location="before">
    </dxi-item>
</dx-toolbar>
<dx-drawer ...
    [(opened)]="isDrawerOpen">
    <div>View content</div>
</dx-drawer>
import { Component } from "@angular/core";

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})

export class AppComponent {
    isDrawerOpen: Boolean = false;
    buttonOptions: any = {
        icon: "menu",
        onClick: () => {
            this.isDrawerOpen = !this.isDrawerOpen;
        }
    }
}
// ...
import { DxDrawerModule, DxToolbarModule } from "devextreme-angular";

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        // ...
        DxDrawerModule,
        DxToolbarModule,
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule { }
/* ... */
::ng-deep #toolbar {
    background-color: rgba(191, 191, 191, .15);
    padding: 5px 10px;
}
::ng-deep .dx-toolbar-button .dx-button {
    background-color: rgba(191, 191, 191, -0.15);
    border: none;
}
::ng-deep .dx-toolbar-button > .dx-toolbar-item-content {
    margin-left: -7px;
}
Vue
App.vue
<template>
    <div>
        <DxToolbar id="toolbar">
            <DxItem
                widget="dxButton"
                :options="buttonOptions"
                location="before"
            />
        </DxToolbar>
        <DxDrawer ...
            :opened.sync="isDrawerOpen">
            <!-- ... -->
        </DxDrawer>
    </div>
</template>

<script>
// ...
import DxToolbar, { DxItem } from 'devextreme-vue/toolbar';

export default {
    components: {
        // ...
        DxToolbar,
        DxItem
    },
    data() {
        return {
            buttonOptions: {
                icon: "menu",
                onClick: () => {
                    this.isDrawerOpen = !this.isDrawerOpen;
                }
            },
            isDrawerOpen: false
        };
    }
};
</script>

<style>
/* ... */
#toolbar {
    background-color: rgba(191, 191, 191, 0.15);
    padding: 5px 10px;
}
.dx-toolbar-button .dx-button {
    background-color: rgba(191, 191, 191, -0.15);
    border: none;
}
.dx-toolbar-button > .dx-toolbar-item-content {
    margin-left: -7px;
}
</style>
React
NavigationDrawer.js
NavigationDrawer.css
// ...
import { Drawer } from "devextreme-react/drawer";
import { Toolbar, Item } from "devextreme-react/toolbar";

class NavigationDrawer extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isDrawerOpen: false
        };
        this.buttonOptions = {
            icon: "menu",
            onClick: () => {
                this.setState({ isDrawerOpen: !this.state.isDrawerOpen })
            }
        };
    }
    render() {
        return (
            <React.Fragment>
                <Toolbar id="toolbar">
                    <Item 
                        widget="dxButton" 
                        options={this.buttonOptions} 
                        location="before" />
                </Toolbar>
                <Drawer ...
                    opened={this.state.isDrawerOpen} >
                    <div>View content</div>
                </Drawer>
            </React.Fragment>
        );
    }
}
export default NavigationDrawer;
/* ... */
#toolbar {
    background-color: rgba(191, 191, 191, .15);
    padding: 5px 10px;
}
.dx-toolbar-button .dx-button {
    background-color: rgba(191, 191, 191, -0.15);
    border: none;
}
.dx-toolbar-button > .dx-toolbar-item-content {
    margin-left: -7px;
}
ASP.NET MVC Controls
_Layout.cshtml
Site.css
@(Html.DevExtreme().Toolbar()
    .ID("layout-toolbar")
    .Items(items =>{
        items.Add().Widget(w => w.Button()
            .Icon("menu")
            .OnClick("button_clickHandler")
        ).Location(ToolbarItemLocation.Before);
    })
)
@(Html.DevExtreme().Drawer()
    .ID("layout-drawer")
    // ...
)

<script type="text/javascript">
    function button_clickHandler() {
        const drawer = $("#layout-drawer").dxDrawer("instance");
        drawer.toggle();
    }
</script>
/* ... */
#layout-toolbar {
    background-color: rgba(191, 191, 191, .15);
    padding: 5px 10px;
}

#layout-toolbar .dx-toolbar-button .dx-button {
    background-color: rgba(191, 191, 191, -0.15);
    border: none;
}

#layout-toolbar .dx-toolbar-button > .dx-toolbar-item-content {
    margin-left: -7px;
}

Implement Navigation

The Drawer is designed to contain navigation items. If they should nest other items, use the TreeView UI component to implement navigation. Otherwise, use the List, as done in this tutorial.

Each list item should navigate to a different view. To implement this, follow the steps below:

jQuery
  1. Enable item selection

    Set the selectionMode to "single". If you use the TreeView, you should also set the selectByClick property to true.

  2. Navigate to a view when selection is changed

    In the onSelectionChanged event handler, load the new view and hide the Drawer.

index.js
index.html
style.css
pages/inbox.html
pages/sent-mail.html
pages/trash.html
pages/spam.html
$(function() {
    // Loads the initial page
    $("#view" ).load( "./pages/inbox.html" );

    const drawer = $("#drawer").dxDrawer({
        // ...
        template: function(e) {
            const $list = $("<div/>").dxList({
                items: [
                    { id: 1, text: "Inbox", icon: "message", path: "inbox" },
                    { id: 2, text: "Sent Mail", icon: "check", path: "sent-mail" },
                    { id: 3, text: "Trash", icon: "trash", path: "trash" },
                    { id: 4, text: "Spam", icon: "mention", path: "spam" }
                ],
                width: 200,
                selectionMode: "single",
                onSelectionChanged: function(e) {
                    $("#view").load( "./pages/" + e.addedItems[0].path + ".html" );
                    drawer.hide();
                }
            });
            return $list;
        }
    }).dxDrawer("instance");
})
<div id="toolbar"></div>
<div id="drawer">
    <div id="view"></div>
</div>
/* ... */
.dx-list-item-icon {
    margin-right: 10px;
}
<div>Inbox</div>
<div>Sent Mail</div>
<div>Trash</div>
<div>Spam</div>
Angular
  1. Configure routing

    Specify routes and set up the router in the AppRountingModule.

  2. Define an itemTemplate

    Specify the elements that the template should render and wrap them in an element with the RouterLink directive. In the code below, the "links" itemTemplate renders an icon and text.

  3. Enable item selection

    Set the selectionMode to "single". If you use the TreeView, you should also set the selectByClick property to true. In the onSelectionChanged event handler, close the Drawer.

app.component.html
app.component.ts
app.component.css
app-routing.module.ts
app.module.ts
inbox.component.ts
sent-mail.component.ts
spam.component.ts
trash.component.ts
<dx-drawer ... >
    <div *dxTemplate="let data of 'template'">
        <dx-list
            [items]="navigation"
            [width]="200"
            selectionMode="single"
            (onSelectionChanged)="this.isDrawerOpen = false"
            itemTemplate="links">
            <div *dxTemplate="let link of 'links'">
                <a [routerLink]="['/' + link.path]">
                    <div>
                        <div class="dx-list-item-icon-container">
                            <i class="dx-icon dx-list-item-icon dx-icon-{{link.icon}}"></i>
                        </div>
                        <span>{{ link.text }}</span>
                    </div>
                </a>
            </div>
        </dx-list>
    </div>
    <div id="view">
        <router-outlet></router-outlet>
    </div>
</dx-drawer>
import { Component } from "@angular/core";

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    navigation: any[] = [
        { id: 1, text: "Inbox", icon: "message", path: "inbox" },
        { id: 2, text: "Sent Mail", icon: "check", path: "sent-mail" },
        { id: 3, text: "Trash", icon: "trash", path: "trash" },
        { id: 4, text: "Spam", icon: "mention", path: "spam" }
    ];
    isDrawerOpen: Boolean = false;
}
/* ... */
::ng-deep .dx-list-item-icon {
    margin-right: 10px;
}
import { NgModule } from "@angular/core";
import { Routes, RouterModule } from "@angular/router";
import { InboxComponent } from "./views/inbox.component";
import { SentMailComponent } from "./views/sent-mail.component";
import { TrashComponent } from "./views/trash.component";
import { SpamComponent } from "./views/spam.component";

const routes: Routes = [
    { path: '', redirectTo: '/inbox', pathMatch: 'full' },
    { path: 'inbox', component: InboxComponent },
    { path: 'sent-mail', component: SentMailComponent },
    { path: 'trash', component: TrashComponent },
    { path: 'spam', component: SpamComponent },
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule],
    declarations: [
        InboxComponent,
        SentMailComponent,
        TrashComponent,
        SpamComponent
    ]
})
export class AppRoutingModule { }
import { AppRoutingModule } from "./app-routing.module";
import { DxDrawerModule, DxToolbarModule, DxListModule } from "devextreme-angular";
// ...
@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        // ...
        AppRoutingModule,
        DxDrawerModule,
        DxToolbarModule,
        DxListModule
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule { }
import { Component } from "@angular/core";

@Component({
    selector: 'app-inbox',
    template: '<div>Inbox</div>'
})
export class InboxComponent { constructor() { } }
import { Component } from "@angular/core";

@Component({
    selector: 'app-sent-mail',
    template: '<div>Sent Mail</div>'
})
export class SentMailComponent { constructor() { } }
import { Component } from "@angular/core";

@Component({
    selector: 'app-spam',
    template: '<div>Spam</div>'
})
export class SpamComponent { constructor() { } }
import { Component } from "@angular/core";

@Component({
    selector: 'app-trash',
    template: '<div>Trash</div>'
})
export class TrashComponent { constructor() { } }
Vue
  1. Install Vue Router

    npm install vue-router
  2. Configure routing

    Specify routes and set up the router in the main.js file.

  3. Define an itemTemplate

    Specify the elements that the template should render and wrap them in a <router-link> component. In the code below, the "links" itemTemplate renders an icon and text.

  4. Enable item selection

    Set the selectionMode to "single". If you use the TreeView, you should also set the selectByClick property to true. In the onSelectionChanged event handler, close the Drawer.

NavigationList.vue
App.vue
main.js
Inbox.vue
SentMail.vue
Spam.vue
Trash.vue
<template>
    <DxList
        :width="200"
        selection-mode="single"
        :items="navigation"
        item-template="links"
        @selection-changed="navigate">
        <template #links="{ data }">
            <div>
                <router-link :to="'/' + data.path">
                    <div>
                        <div class="dx-list-item-icon-container">
                            <i class="dx-icon dx-list-item-icon" :class="'dx-icon-' + data.icon"></i>
                        </div>
                        <span>{{ data.text }}</span>
                    </div>
                </router-link>
            </div>
        </template>
    </DxList>
</template>
<script>
import { DxList } from "devextreme-vue/list";

export default {
    components: {
        DxList
    },
    data() {
        const navigation = [
            { id: 1, text: "Inbox", icon: "message", path: "inbox" },
            { id: 2, text: "Sent Mail", icon: "check", path: "sent-mail" },
            { id: 3, text: "Trash", icon: "trash", path: "trash" },
            { id: 4, text: "Spam", icon: "mention", path: "spam" }
        ];
        return {
            navigation
        };
    },
    methods: {
        navigate() {
            this.$emit('navigated');
        }
    }
}
</script>
<template>
    <div>
        <!-- ... -->
        <DxDrawer ...
            template="list">
            <template #list>
                <NavigationList
                    @navigated="isDrawerOpen = false"
                />
            </template>
            <div id="view">
                <router-view></router-view>
            </div>
        </DxDrawer>
    </div>
</template>

<script>
// ...
import NavigationList from './components/NavigationList.vue';

export default {
    components: {
        // ...
        NavigationList
    },
    // ...
};
</script>

<style>
/* ... */
.dx-list-item-icon {
    margin-right: 10px;
}
</style>
import Vue from 'vue';
import VueRouter from 'vue-router';

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

import App from './App.vue';
import InboxComponent from "./components/Inbox.vue";
import SentMailComponent from "./components/SentMail.vue";
import TrashComponent from "./components/Trash.vue";
import SpamComponent from "./components/Spam.vue";

Vue.config.productionTip = false;

Vue.use(VueRouter);

const routes = [
    { path: "", redirect: "/inbox" },
    { path: "/inbox", component: InboxComponent },
    { path: "/sent-mail", component: SentMailComponent },
    { path: "/trash", component: TrashComponent },
    { path: "/spam", component: SpamComponent }
];

const router = new VueRouter({
    mode: "history",
    routes
});

new Vue({
    render: h => h(App),
    router
}).$mount('#app')
<template>
    <div>Inbox</div>
</template>

<script>
export default {}
</script>
<template>
    <div>Sent mail</div>
</template>

<script>
export default {}
</script>
<template>
    <div>Spam</div>
</template>

<script>
export default {}
</script>
<template>
    <div>Trash</div>
</template>

<script>
export default {}
</script>
React
  1. Install React Router

    npm install react-router-dom --save
  2. Configure routing

    Wrap the entire App component in a BrowserRouter and add a Route that renders the NavigationDrawer component. Define other Routes within the Drawer markup in the NavigationDrawer component.

  3. Define the itemRender function

    Specify the elements that the function should render and wrap them in a Link. In the code below, the renderItem function renders an icon and text.

  4. Enable item selection

    Set the selectionMode to "single". If you use the TreeView, you should also set the selectByClick property to true. In the onSelectionChanged event handler, close the Drawer.

App.js
NavigationDrawer.js
NavigationList.js
NavigationDrawer.css
views/Inbox.js
views/SentMail.js
views/Spam.js
views/Trash.js
// ...
import { BrowserRouter, Route } from 'react-router-dom'

class App extends Component {
    render() {
        return (
            <BrowserRouter>
                <div className="App">
                    <Route component={NavigationDrawer} />
                </div>
            </BrowserRouter>
        );
    }
}
export default App;
// ...
import NavigationList from "./NavigationList";

import { Switch, Route } from "react-router-dom";

import Inbox from "./views/Inbox";
import Trash from "./views/Trash";
import SentMail from "./views/SentMail";
import Spam from "./views/Spam";

class NavigationDrawer extends React.Component {
    // ...
    renderList = () => {
        const stateHandler = (newState) => this.setState(newState);
        return (
            <NavigationList stateHandler={stateHandler} />
        );
    }

    render() {
        return (
            <React.Fragment>
                { /* ... */ }
                <Drawer ...
                    render={this.renderList}>
                    <div id="view">
                        <Switch>
                            <Route exact path="/" component={Inbox} />
                            <Route exact path="/inbox" component={Inbox} />
                            <Route exact path="/sent-mail" component={SentMail} />
                            <Route exact path="/spam" component={Spam} />
                            <Route exact path="/trash" component={Trash} />
                        </Switch>
                    </div>
                </Drawer>
            </React.Fragment>
        );
    }
}
export default NavigationDrawer;
import React from "react";
import List from "devextreme-react/list";
import { Link } from "react-router-dom";

const navigation = [
    { id: 1, text: "Inbox", icon: "message", path: "inbox" },
    { id: 2, text: "Sent Mail", icon: "check", path: "sent-mail" },
    { id: 3, text: "Trash", icon: "trash", path: "trash" },
    { id: 4, text: "Spam", icon: "mention", path: "spam" }
];

class NavigationList extends React.PureComponent {
    closeDrawer = () => {
        this.props.stateHandler({ isDrawerOpen: false });
    }

    renderItem = (data) => {
        return (
            <div>
                <Link to={'/' + data.path}>
                    <div>
                        <div className="dx-list-item-icon-container">
                            <i className={`dx-icon dx-list-item-icon dx-icon-${data.icon}`}></i>
                        </div>
                        <span>{data.text}</span>
                    </div>
                </Link>
            </div>
        );
    }

    render() {
        return (
            <React.Fragment>
                <List
                    items={navigation}
                    width={200} 
                    selectionMode="single"
                    onSelectionChanged={this.closeDrawer}
                    itemRender={this.renderItem}
                />
            </React.Fragment>
        );
    }
}
export default NavigationList;
/* ... */
.dx-list-item-icon {
    margin-right: 10px;
}
import React from "react";

class Inbox extends React.Component {
    render() {
        return (
            <div>Inbox</div>
        );
    }
}
export default Inbox;
import React from "react";

class SentMail extends React.Component {
    render() {
        return (
            <div>Sent Mail</div>
        );
    }
}
export default SentMail;
import React from "react";

class Spam extends React.Component {
    render() {
        return (
            <div>Spam</div>
        );
    }
}
export default Spam;
import React from "react";

class Trash extends React.Component {
    render() {
        return (
            <div>Trash</div>
        );
    }
}
export default Trash;
ASP.NET MVC Controls
  1. Enable item selection

    Set the selectionMode to "single". If you use the TreeView, you should also set the selectByClick property to true.

  2. Navigate to a view when selection is changed

    In the onSelectionChanged event handler, load the new view and hide the Drawer.

_Layout.cshtml
HomeController.cs
Site.css
Index.cshtml
Deleted.cshtml
Sent.cshtml
Spam.cshtml
@(Html.DevExtreme().Toolbar()
    // ...
)
@(Html.DevExtreme().Drawer()
    .ID("layout-drawer")   
    .Template(@<text>
        @(Html.DevExtreme().List()
            .Width(200)
            .OnInitialized("list_onInitialized")
            .Items(items => {
                items.Add().Text("Inbox").Icon("message").Option("path", @Url.Action("Index"));
                items.Add().Text("Sent Mail").Icon("check").Option("path", @Url.Action("Sent"));
                items.Add().Text("Deleted").Icon("trash").Option("path", @Url.Action("Deleted"));
                items.Add().Text("Spam").Icon("mention").Option("path", @Url.Action("Spam"));
            })
            .KeyExpr("path")
            .SelectionMode(ListSelectionMode.Single)
            .OnSelectionChanged("list_onSelectionChanged")
        )
    </text>)
    .Content(@<text>@RenderBody()</text>)
)

<script type="text/javascript">
    function button_clickHandler() {
        // ...
        sessionStorage.setItem("isDrawerOpen", JSON.stringify(drawer.option("opened")));
    }

    function list_onSelectionChanged(e) {
        const drawer = $("#layout-drawer").dxDrawer("instance");
        drawer.hide();
        sessionStorage.setItem("isDrawerOpen", JSON.stringify(drawer.option("opened")));
        document.location.pathname = e.addedItems[0].path;
    }

    function list_onInitialized(e) {
        const t = "@Url.Action()";
        e.component.option("selectedItemKeys", [ "@Url.Action()" ])
    }
</script>
using System.Web.Mvc;

namespace DevExtremeApp.Controllers {
    public class HomeController : Controller {
        public ActionResult Index() {
            return View();
        }

        public ActionResult Deleted() {
            return View();
        }

        public ActionResult Sent() {
            return View();
        }

        public ActionResult Spam() {
            return View();
        }
    }
}
/* ... */
#layout-toolbar .dx-list-item-icon {
    margin-right: 10px;
}
<div class="drawer-view-content">Inbox</div>
<div class="drawer-view-content">Deleted</div>
<div class="drawer-view-content">Sent</div>
<div class="drawer-view-content">Spam</div>

Run the code, open the Drawer, and click its items to change the views.

Configure the Reveal Behavior

When you open the Drawer, it can slide in or expand from the closed position. Use the revealMode property to specify this behavior.

jQuery
index.js
$(function() {
    const drawer = $("#drawer").dxDrawer({
        // ...
        revealMode: "expand"
    }).dxDrawer("instance");
})
Angular
app.component.html
<dx-drawer ...
    revealMode="expand">
</dx-drawer>
Vue
App.vue
<template>
    <div>
        <!-- ... -->
        <DxDrawer ...
            reveal-mode="expand">
            <!-- ... -->
        </DxDrawer>
    </div>
</template>

<script>
// ...
</script>
React
NavigationDrawer.js
// ...
class NavigationDrawer extends React.Component {
    // ...
    render() {
        return (
            <React.Fragment>
                <Drawer ...
                    revealMode="expand" >
                </Drawer>
            </React.Fragment>
        );
    }
}
export default NavigationDrawer;
ASP.NET MVC Controls
_Layout.cshtml
@(Html.DevExtreme().Drawer()
    .ID("layout-drawer")   
    .RevealMode(DrawerRevealMode.Expand)
)

Run the code and open the Drawer. You should see that the UI component gets wider, but its content stays in place, creating an impression that the Drawer expands.

Configure Interaction with the View

When the Drawer opens, it can overlap, shrink, or partially displace the view, depending on the openedStateMode property:

jQuery
index.js
$(function() {
    const drawer = $("#drawer").dxDrawer({
        // ...
        openedStateMode: "overlap"
    }).dxDrawer("instance");
})
Angular
app.component.html
<dx-drawer ...
    openedStateMode="overlap">
</dx-drawer>
Vue
App.vue
<template>
    <div>
        <!-- ... -->
        <DxDrawer ...
            opened-state-mode="overlap">
            <!-- ... -->
        </DxDrawer>
    </div>
</template>

<script>
// ...
</script>
React
NavigationDrawer.js
// ...
class NavigationDrawer extends React.Component {
    // ...
    render() {
        return (
            <React.Fragment>
                <Drawer ...
                    openedStateMode="overlap" >
                </Drawer>
            </React.Fragment>
        );
    }
}
export default NavigationDrawer;
ASP.NET MVC Controls
_Layout.cshtml
@(Html.DevExtreme().Drawer()
    .ID("layout-drawer")   
    .OpenedStateMode(DrawerOpenedStateMode.Overlap)
)

Run the code, open the Drawer and you should see that it overlaps the view's text.

Change the Position

You can use the position property to anchor the Drawer to any side of the view. In this tutorial, the Drawer is in its default position (left).

You have configured basic Drawer features. For more information about this UI component, explore the following resources: