Dialog in React Kanban Component
9 Sep 202524 minutes to read
The Kanban component provides a built-in dialog module for adding, editing, and deleting cards, configured through the dialogSettings property. User can edit a card using the following ways.
- Built-in dialog module
- Custom Fields
- Dialog template
Default Dialog
Double-clicking a card opens the dialog with fields mapped from cardSettings and swimlaneSettings for editing. The dialog includes Save, Delete, and Cancel buttons:
- Save: Updates the card with modified details.
- Delete: Removes the selected card.
- Cancel: Discards changes.
The dialog displays with the following fields which mapped to dialog fields by default.
| Key | Type | Text |
|---|---|---|
cardSettings.headerField |
Input | ID |
keyField |
DropDown | - |
cardSettings.contentField |
TextArea | - |
cardSettings.priority (If applicable) |
Numeric | - |
swimlaneSettings.keyField (If applicable) |
DropDown | - |
The following sample demonstrates the default dialog for card editing.
[Class-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
class App extends React.Component {
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
}
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="In Progress" keyField="InProgress"/>
<ColumnDirective headerText="Testing" keyField="Testing"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>;
}
}
;
ReactDOM.render(<App />, document.getElementById('kanban'));import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective, DialogFieldsModel } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
class App extends React.Component<{}, {}>{
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
}
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
}
};
ReactDOM.render(<App />, document.getElementById('kanban'));<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban Cards</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban Cards" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>[Functional-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
function App() {
let data = extend([], kanbanData, null, true);
return (<KanbanComponent id="kanban" keyField="Status" dataSource={data} cardSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="In Progress" keyField="InProgress"/>
<ColumnDirective headerText="Testing" keyField="Testing"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>);
}
ReactDOM.render(<App />, document.getElementById('kanban'));import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective, DialogFieldsModel } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
function App(){
let data = extend([], kanbanData, null, true);
return(
<KanbanComponent id="kanban" keyField="Status" dataSource={data} cardSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
);
}
ReactDOM.render(<App />, document.getElementById('kanban'));<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban Cards</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban Cards" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>Custom Fields
Customize dialog fields using the fields property in dialogSettings. The key property maps to the dataSource value, and the type property specifies the component type. Available types include:
- String
- Numeric
- TextArea
- DropDown
- TextBox
- Input
If
typeis not defined in the fields, then it renders as the HTML input element in dialog.
The following sample demonstrates custom dialog fields.
[Class-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
class App extends React.Component {
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
}
fields = [
{ key: 'Id', type: 'Input' },
{ key: 'Status', type: 'DropDown' },
{ key: 'Estimate', type: 'Numeric' },
{ key: 'Summary', type: 'TextArea' }
];
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings= dialogSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="In Progress" keyField="InProgress"/>
<ColumnDirective headerText="Testing" keyField="Testing"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>;
}
}
;
ReactDOM.render(<App />, document.getElementById('kanban'));import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective, DialogFieldsModel } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
class App extends React.Component<{}, {}>{
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
}
private fields: DialogFieldsModel[] = [
{ key: 'Id', type: 'Input' },
{ key: 'Status', type: 'DropDown' },
{ key: 'Estimate', type: 'Numeric' },
{ key: 'Summary', type: 'TextArea' }
];
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings= dialogSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
}
};
ReactDOM.render(<App />, document.getElementById('kanban'));<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban Custom Label Dialog</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban Custom Label Dialog" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>[Functional-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
function App() {
let data = extend([], kanbanData, null, true);
let fields = [
{ key: 'Id', type: 'Input' },
{ key: 'Status', type: 'DropDown' },
{ key: 'Estimate', type: 'Numeric' },
{ key: 'Summary', type: 'TextArea' }
];
return (<KanbanComponent id="kanban" keyField="Status" dataSource={data} cardSettings= dialogSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="In Progress" keyField="InProgress"/>
<ColumnDirective headerText="Testing" keyField="Testing"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>);
}
ReactDOM.render(<App />, document.getElementById('kanban'));import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective, DialogFieldsModel } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
function App(){
let data = extend([], kanbanData, null, true);
let fields: DialogFieldsModel[] = [
{ key: 'Id', type: 'Input' },
{ key: 'Status', type: 'DropDown' },
{ key: 'Estimate', type: 'Numeric' },
{ key: 'Summary', type: 'TextArea' }
];
return(
<KanbanComponent id="kanban" keyField="Status" dataSource={data} cardSettings= dialogSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
);
}
ReactDOM.render(<App />, document.getElementById('kanban'));<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban Custom Label Dialog</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban Custom Label Dialog" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>Custom Fields label
By default, the fields key mapping value is considered as a label and you can change this label by using text property. The following sample shows custom labels for dialog fields.
[Class-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
class App extends React.Component {
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
}
fields = [
{ text: 'ID', key: 'Id', type: 'TextBox' },
{ key: 'Status', type: 'DropDown' },
{ key: 'Estimate', type: 'Numeric' },
{ key: 'Summary', type: 'TextArea' }
];
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings= dialogSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="In Progress" keyField="InProgress"/>
<ColumnDirective headerText="Testing" keyField="Testing"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>;
}
}
;
ReactDOM.render(<App />, document.getElementById('kanban'));import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective, DialogFieldsModel } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
class App extends React.Component<{}, {}>{
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
}
private fields: DialogFieldsModel[] = [
{ text: 'ID', key: 'Id', type: 'TextBox' },
{ key: 'Status', type: 'DropDown' },
{ key: 'Estimate', type: 'Numeric' },
{ key: 'Summary', type: 'TextArea' }
];
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings= dialogSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
}
};
ReactDOM.render(<App />, document.getElementById('kanban'));<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban Label Dialog</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban Label Dialog" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>[Functional-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
function App() {
let data = extend([], kanbanData, null, true);
let fields = [
{ text: 'ID', key: 'Id', type: 'TextBox' },
{ key: 'Status', type: 'DropDown' },
{ key: 'Estimate', type: 'Numeric' },
{ key: 'Summary', type: 'TextArea' }
];
return (<KanbanComponent id="kanban" keyField="Status" dataSource={data} cardSettings= dialogSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="In Progress" keyField="InProgress"/>
<ColumnDirective headerText="Testing" keyField="Testing"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>);
}
ReactDOM.render(<App />, document.getElementById('kanban'));import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective, DialogFieldsModel } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
function App(){
let data = extend([], kanbanData, null, true);
let fields: DialogFieldsModel[] = [
{ text: 'ID', key: 'Id', type: 'TextBox' },
{ key: 'Status', type: 'DropDown' },
{ key: 'Estimate', type: 'Numeric' },
{ key: 'Summary', type: 'TextArea' }
];
return(
<KanbanComponent id="kanban" keyField="Status" dataSource={data} cardSettings= dialogSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
);
}
ReactDOM.render(<App />, document.getElementById('kanban'));<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban Label Dialog</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban Label Dialog" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>Fields Validation
The dialog fields can be validated while click on the Save button. This can be achieved by using validationRules property. The following sample demonstrates field validation.
[Class-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
class App extends React.Component {
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
}
fields = [
{ text: 'ID', key: 'Id', type: 'Input' },
{ key: 'Status', type: 'DropDown' },
{ key: 'Estimate', type: 'Numeric', validationRules: { range: [0, 1000] } },
{ key: 'Summary', type: 'TextArea', validationRules: { required: true } }
];
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings= dialogSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="In Progress" keyField="InProgress"/>
<ColumnDirective headerText="Testing" keyField="Testing"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>;
}
}
;
ReactDOM.render(<App />, document.getElementById('kanban'));import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective, DialogFieldsModel } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
class App extends React.Component<{}, {}>{
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
}
private fields: DialogFieldsModel[] = [
{ text: 'ID', key: 'Id', type: 'Input' },
{ key: 'Status', type: 'DropDown' },
{ key: 'Estimate', type: 'Numeric', validationRules: { range: [0, 1000] } },
{ key: 'Summary', type: 'TextArea', validationRules: { required: true } }
];
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings= dialogSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
}
};
ReactDOM.render(<App />, document.getElementById('kanban'));<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban Dialog Fields Validation</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban Dialog Fields Validation" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>[Functional-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
function App() {
let data = extend([], kanbanData, null, true);
let fields = [
{ text: 'ID', key: 'Id', type: 'Input' },
{ key: 'Status', type: 'DropDown' },
{ key: 'Estimate', type: 'Numeric', validationRules: { range: [0, 1000] } },
{ key: 'Summary', type: 'TextArea', validationRules: { required: true } }
];
return (<KanbanComponent id="kanban" keyField="Status" dataSource={data} cardSettings= dialogSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="In Progress" keyField="InProgress"/>
<ColumnDirective headerText="Testing" keyField="Testing"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>);
}
ReactDOM.render(<App />, document.getElementById('kanban'));import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective, DialogFieldsModel } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
function App(){
let data = extend([], kanbanData, null, true);
let fields: DialogFieldsModel[] = [
{ text: 'ID', key: 'Id', type: 'Input' },
{ key: 'Status', type: 'DropDown' },
{ key: 'Estimate', type: 'Numeric', validationRules: { range: [0, 1000] } },
{ key: 'Summary', type: 'TextArea', validationRules: { required: true } }
];
return(
<KanbanComponent id="kanban" keyField="Status" dataSource={data} cardSettings= dialogSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
);
}
ReactDOM.render(<App />, document.getElementById('kanban'));<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban Dialog Fields Validation</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban Dialog Fields Validation" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>Dialog Template
Using the dialog template, you can render your own dialog by defining the template property. Initialize the template as SCRIPT element Id or HTML string which holds the template and map it to the template property.
[Class-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
class App extends React.Component {
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
}
dialogTemplate(props) {
return (<KanbanDialogFormTemplate {...props}/>);
}
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings= dialogSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="In Progress" keyField="InProgress"/>
<ColumnDirective headerText="Testing" keyField="Testing"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>;
}
}
;
ReactDOM.render(<App />, document.getElementById('kanban'));
export class KanbanDialogFormTemplate extends React.Component {
assigneeData = [
'Nancy Davloio', 'Andrew Fuller', 'Janet Leverling',
'Steven walker', 'Robert King', 'Margaret hamilt', 'Michael Suyama'
];
statusData = ['Open', 'InProgress', 'Testing', 'Close'];
priorityData = ['Low', 'Normal', 'Critical', 'Release Breaker', 'High'];
tagsHtmlAttributes = { name: "Tags" };
constructor(props) {
super(props);
this.state = extend({}, {}, props, true);
}
onChange(args) {
let key = args.target.name;
let value = args.target.value;
this.setState({ [key]: value });
}
render() {
let data = this.state;
return (<div>
<table>
<tbody>
<tr>
<td className="e-label">ID</td>
<td>
<div className="e-float-input e-control-wrapper">
<input id="Id" name="Id" type="text" className="e-field" value={data.Id} disabled/>
</div>
</td>
</tr>
<tr>
<td className="e-label">Status</td>
<td>
<DropDownListComponent id='Status' name="Status" dataSource={this.statusData} className="e-field" placeholder='Status' value={data.Status}></DropDownListComponent>
</td>
</tr>
<tr>
<td className="e-label">Assignee</td>
<td>
<DropDownListComponent id='Assignee' name="Assignee" className="e-field" dataSource={this.assigneeData} placeholder='Assignee' value={data.Assignee}></DropDownListComponent>
</td>
</tr>
<tr>
<td className="e-label">Priority</td>
<td>
<DropDownListComponent type="text" name="Priority" id="Priority" popupHeight='300px' className="e-field" value={data.Priority} dataSource={this.priorityData} placeholder='Priority'></DropDownListComponent>
</td>
</tr>
<tr>
<td className="e-label">Summary</td>
<td>
<div className="e-float-input e-control-wrapper">
<textarea name="Summary" className="e-field" value={data.Summary} onChange={this.onChange.bind(this)}></textarea>
</div>
</td>
</tr>
</tbody>
</table>
</div>);
}
}import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
class App extends React.Component<{}, {}>{
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
}
private dialogTemplate(props: KanbanDataModel): JSX.Element {
return (<KanbanDialogFormTemplate {...props} />);
}
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings= dialogSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
}
};
ReactDOM.render(<App />, document.getElementById('kanban'));
export class KanbanDialogFormTemplate extends React.Component<{}, {}> {
public assigneeData: string[] = [
'Nancy Davloio', 'Andrew Fuller', 'Janet Leverling',
'Steven walker', 'Robert King', 'Margaret hamilt', 'Michael Suyama'
];
public statusData: string[] = ['Open', 'InProgress', 'Testing', 'Close'];
public priorityData: string[] = ['Low', 'Normal', 'Critical', 'Release Breaker', 'High'];
public tagsHtmlAttributes = { name: "Tags" };
constructor(props) {
super(props);
this.state = extend({}, {}, props, true);
}
onChange(args: any): void {
let key: string = args.target.name;
let value: string = args.target.value;
this.setState({ [key]: value });
}
render(): any {
let data: KanbanDataModel = this.state;
return (<div>
<table>
<tbody>
<tr>
<td className="e-label">ID</td>
<td>
<div className="e-float-input e-control-wrapper">
<input id="Id" name="Id" type="text" className="e-field" value={data.Id} disabled />
</div>
</td>
</tr>
<tr>
<td className="e-label">Status</td>
<td>
<DropDownListComponent id='Status' name="Status" dataSource={this.statusData} className="e-field" placeholder='Status' value={data.Status}></DropDownListComponent>
</td>
</tr>
<tr>
<td className="e-label">Assignee</td>
<td>
<DropDownListComponent id='Assignee' name="Assignee" className="e-field" dataSource={this.assigneeData} placeholder='Assignee' value={data.Assignee}></DropDownListComponent>
</td>
</tr>
<tr>
<td className="e-label">Priority</td>
<td>
<DropDownListComponent type="text" name="Priority" id="Priority" popupHeight='300px' className="e-field" value={data.Priority} dataSource={this.priorityData} placeholder='Priority'></DropDownListComponent>
</td>
</tr>
<tr>
<td className="e-label">Summary</td>
<td>
<div className="e-float-input e-control-wrapper">
<textarea name="Summary" className="e-field" value={data.Summary} onChange={this.onChange.bind(this)}></textarea>
</div>
</td>
</tr>
</tbody>
</table>
</div>);
}
}
export interface KanbanDataModel {
Id?: string;
Title?: string;
Status?: string;
Summary?: string;
Type?: string;
Priority?: string;
Tags?: string;
Estimate?: number;
Assignee?: string;
RankId?: number;
Color?: string;
}<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban Dialog Template</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban Dialog Template" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>[Functional-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
import { DropDownListComponent } from "@syncfusion/ej2-react-dropdowns";
function App() {
let data = extend([], kanbanData, null, true);
let kanbanObj;
function dialogTemplate(props) {
return (<KanbanDialogFormTemplate {...props}/>);
}
return (<KanbanComponent id="kanban" keyField="Status" dataSource={data} cardSettings= dialogSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="In Progress" keyField="InProgress"/>
<ColumnDirective headerText="Testing" keyField="Testing"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>);
}
function KanbanDialogFormTemplate(props) {
let assigneeData = [
'Nancy Davloio', 'Andrew Fuller', 'Janet Leverling',
'Steven walker', 'Robert King', 'Margaret hamilt', 'Michael Suyama'
];
let statusData = ['Open', 'InProgress', 'Testing', 'Close'];
let priorityData = ['Low', 'Normal', 'Critical', 'Release Breaker', 'High'];
let tagsHtmlAttributes = { name: "Tags" };
const [state, setState] = React.useState(extend({}, {}, props, true));
function onChange(args) {
let key = args.target.name;
let value = args.target.value;
setState({ [key]: value });
}
let data = state;
return (<div>
<table>
<tbody>
<tr>
<td className="e-label">ID</td>
<td>
<div className="e-float-input e-control-wrapper">
<input id="Id" name="Id" type="text" className="e-field" value={data.Id} disabled/>
</div>
</td>
</tr>
<tr>
<td className="e-label">Status</td>
<td>
<DropDownListComponent id='Status' name="Status" dataSource={statusData} className="e-field" placeholder='Status' value={data.Status}></DropDownListComponent>
</td>
</tr>
<tr>
<td className="e-label">Assignee</td>
<td>
<DropDownListComponent id='Assignee' name="Assignee" className="e-field" dataSource={assigneeData} placeholder='Assignee' value={data.Assignee}></DropDownListComponent>
</td>
</tr>
<tr>
<td className="e-label">Priority</td>
<td>
<DropDownListComponent type="text" name="Priority" id="Priority" popupHeight='300px' className="e-field" value={data.Priority} dataSource={priorityData} placeholder='Priority'></DropDownListComponent>
</td>
</tr>
<tr>
<td className="e-label">Summary</td>
<td>
<div className="e-float-input e-control-wrapper">
<textarea name="Summary" className="e-field" value={data.Summary} onChange={onChange.bind(this)}></textarea>
</div>
</td>
</tr>
</tbody>
</table>
</div>);
}
ReactDOM.render(<App />, document.getElementById('kanban'));import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
import { DropDownListComponent } from '@syncfusion/ej2-react-dropdowns';
function App() {
let data = extend([], kanbanData, null, true);
let kanbanObj: KanbanComponent;
function dialogTemplate(props: KanbanDataModel) {
return (<KanbanDialogFormTemplate {...props} />);
}
return (<KanbanComponent id="kanban" keyField="Status" dataSource={data}
cardSettings= dialogSettings=>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
);
}
function KanbanDialogFormTemplate (props) {
let assigneeData: string[] = [
'Nancy Davloio', 'Andrew Fuller', 'Janet Leverling',
'Steven walker', 'Robert King', 'Margaret hamilt', 'Michael Suyama'
];
let statusData: string[] = ['Open', 'InProgress', 'Testing', 'Close'];
let priorityData: string[] = ['Low', 'Normal', 'Critical', 'Release Breaker', 'High'];
let tagsHtmlAttributes = { name: "Tags" };
const [state, setState] = React.useState(extend({}, {}, props, true));
function onChange(args: any): void {
let key: string = args.target.name;
let value: string = args.target.value;
setState({ [key]: value });
}
let data: KanbanDataModel = state;
return (
<div>
<table>
<tbody>
<tr>
<td className="e-label">ID</td>
<td>
<div className="e-float-input e-control-wrapper">
<input id="Id" name="Id" type="text" className="e-field" value={data.Id} disabled />
</div>
</td>
</tr>
<tr>
<td className="e-label">Status</td>
<td>
<DropDownListComponent id='Status' name="Status" dataSource={statusData} className="e-field" placeholder='Status' value={data.Status}></DropDownListComponent>
</td>
</tr>
<tr>
<td className="e-label">Assignee</td>
<td>
<DropDownListComponent id='Assignee' name="Assignee" className="e-field" dataSource={assigneeData} placeholder='Assignee' value={data.Assignee}></DropDownListComponent>
</td>
</tr>
<tr>
<td className="e-label">Priority</td>
<td>
<DropDownListComponent type="text" name="Priority" id="Priority" popupHeight='300px' className="e-field" value={data.Priority} dataSource={priorityData} placeholder='Priority'></DropDownListComponent>
</td>
</tr>
<tr>
<td className="e-label">Summary</td>
<td>
<div className="e-float-input e-control-wrapper">
<textarea name="Summary" className="e-field" value={data.Summary} onChange={onChange.bind(this)}></textarea>
</div>
</td>
</tr>
</tbody>
</table>
</div>
);
}
export interface KanbanDataModel {
Id?: string;
Title?: string;
Status?: string;
Summary?: string;
Type?: string;
Priority?: string;
Tags?: string;
Estimate?: number;
Assignee?: string;
RankId?: number;
Color?: string;
}
ReactDOM.render(<App />, document.getElementById('kanban'));<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban Dialog Template</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban Dialog Template" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>Prevent Dialog
Prevent the dialog from opening on card double-click by setting args.cancel to true in the dialogOpen event. The following sample demonstrates preventing dialog opening.
[Class-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
class App extends React.Component {
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
}
DialogOpen(args) {
args.cancel = true;
}
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings= dialogOpen={this.DialogOpen.bind(this)}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="In Progress" keyField="InProgress"/>
<ColumnDirective headerText="Testing" keyField="Testing"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>;
}
}
;
ReactDOM.render(<App />, document.getElementById('kanban'));import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective, DialogEventArgs } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
class App extends React.Component<{}, {}>{
constructor() {
super(...arguments);
this.data = extend([], kanbanData, null, true);
}
private DialogOpen(args: DialogEventArgs): void {
args.cancel = true;
}
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings= dialogOpen={this.DialogOpen.bind(this)}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
}
};
ReactDOM.render(<App />, document.getElementById('kanban'));<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban Prevent Dialog Open</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban Prevent Dialog Open" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>[Functional-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
function App() {
let data = extend([], kanbanData, null, true);
function DialogOpen(args) {
args.cancel = true;
}
return (<KanbanComponent id="kanban" keyField="Status" dataSource={data} cardSettings= dialogOpen={DialogOpen.bind(this)}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open"/>
<ColumnDirective headerText="In Progress" keyField="InProgress"/>
<ColumnDirective headerText="Testing" keyField="Testing"/>
<ColumnDirective headerText="Done" keyField="Close"/>
</ColumnsDirective>
</KanbanComponent>);
}
ReactDOM.render(<App />, document.getElementById('kanban'));import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { extend } from '@syncfusion/ej2-base';
import { KanbanComponent, ColumnsDirective, ColumnDirective, DialogEventArgs } from "@syncfusion/ej2-react-kanban";
import { kanbanData } from './datasource';
function App(){
let data = extend([], kanbanData, null, true);
function DialogOpen(args: DialogEventArgs): void {
args.cancel = true;
}
return(
<KanbanComponent id="kanban" keyField="Status" dataSource={data} cardSettings= dialogOpen={DialogOpen.bind(this)}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
);
}
ReactDOM.render(<App />, document.getElementById('kanban'));<!DOCTYPE html>
<html lang="en">
<head>
<title>Kanban Prevent Dialog Open</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Kanban Prevent Dialog Open" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-layouts/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/31.2.12/ej2-react-kanban/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='kanban'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>Persisting data in server
The modified card data can be persisted in the database using the RESTful web services. All the CRUD operations in the Kanban are done through DataManager. The DataManager has an option to bind all the CRUD related data in server-side.
For your information, the ODataAdaptor persists data in the server as per OData protocol.
In the below section covers how to get the edited data details on the server-side using the UrlAdaptor.
URL adaptor
You can use the UrlAdaptor of DataManager when binding data source for remote data. In the initial load of Kanban, data are fetched from remote data and bound to the Kanban using url property of DataManager.
You can map the CRUD operation in Kanban can be mapped to server-side controller actions using the properties insertUrl, removeUrl, updateUrl, and crudUrl.
-
insertUrl– You can perform single insertion operation on server-side. -
updateUrl– You can update single data on server-side. -
removeUrl– You can remove single data on server-side. -
crudUrl– You can perform bulk data operation on server-side.
The following code example describes the above behavior.
[Class-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DataManager, UrlAdaptor } from '@syncfusion/ej2-data';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
class App extends React.Component<{}, {}>{
public data = new DataManager({
url: 'Home/DataSource',
updateUrl: 'Home/Update',
insertUrl: 'Home/Insert',
removeUrl: 'Home/Delete',
adaptor: new UrlAdaptor(),
crossDomain: true
});
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings={{ contentField: "Summary", headerField: "Id" }}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
}
};
ReactDOM.render(<App />, document.getElementById('kanban'));[Functional-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DataManager, UrlAdaptor } from '@syncfusion/ej2-data';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
function App(){
let data = new DataManager({
url: 'Home/DataSource',
updateUrl: 'Home/Update',
insertUrl: 'Home/Insert',
removeUrl: 'Home/Delete',
adaptor: new UrlAdaptor(),
crossDomain: true
});
return (
<KanbanComponent id="kanban" keyField="Status" dataSource={data} cardSettings={{ contentField: "Summary", headerField: "Id" }}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
);
}
ReactDOM.render(<App />, document.getElementById('kanban'));The server-side controller code to handle CRUD operations is as follows.
private NORTHWNDEntities db = new NORTHWNDEntities();
public ActionResult DataSource() {
var DataSource = db.Tasks.ToList();
return Json(DataSource, JsonRequestBehavior.AllowGet);
}
public ActionResult Insert(Params value) {
//Insert card data into the database
return Json(value, JsonRequestBehavior.AllowGet);
}
public ActionResult Update(Params value) {
//Update card data into the database
return Json(value, JsonRequestBehavior.AllowGet);
}
public void Delete(Params value) {
//Delete card data from the database
}
public class Params {
public int Id { get; set; }
public string Status { get; set; }
public string Summary { get; set; }
public string Assignee { get; set; }
}Insert card
Using the insertUrl property, you can specify the controller action mapping URL to perform insert operation on the server-side.
The following code example describes the above behavior.
public ActionResult Insert(Params value)
{
//Insert card in the database
}The newly added record details are bound to the value parameter.
Update card
Using the updateUrl property, the controller action mapping URL can be specified to perform save/update operation on the server-side.
The following code example describes the above behavior.
public ActionResult Update(Params value)
{
//Update card data in the database
}The updated record details are bound to the value parameter.
Delete card
Using the removeUrl property, the controller action mapping URL can be specified to perform delete operation on the server-side.
The following code example describes the above behavior.
public void Delete(int key)
{
//Delete card in the database
}The deleted card primary key value is bound to the key parameter.
CRUD URL
Using the crudUrl property, the controller action mapping URL can be specified to perform all the CRUD operations at the server-side using a single method instead of specifying a separate controller action method for CRUD (insert, update and delete) operations.
The action parameter of crudUrl is used to get the corresponding CRUD action.
The following code example describes the above behavior.
[Class-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DataManager, UrlAdaptor } from '@syncfusion/ej2-data';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
class App extends React.Component<{}, {}>{
public data = new DataManager({
url: 'Home/DataSource',
updateUrl: 'Home/UpdateData',
insertUrl: 'Home/UpdateData',
removeUrl: 'Home/UpdateData',
crudUrl: 'Home/UpdateData',
adaptor: new UrlAdaptor(),
crossDomain: true
});
render() {
return <KanbanComponent id="kanban" keyField="Status" dataSource={this.data} cardSettings={{ contentField: "Summary", headerField: "Id" }}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
}
};
ReactDOM.render(<App />, document.getElementById('kanban'));[Functional-component]
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { DataManager, UrlAdaptor } from '@syncfusion/ej2-data';
import { KanbanComponent, ColumnsDirective, ColumnDirective } from "@syncfusion/ej2-react-kanban";
function App(){
let data = new DataManager({
url: 'Home/DataSource',
updateUrl: 'Home/UpdateData',
insertUrl: 'Home/UpdateData',
removeUrl: 'Home/UpdateData',
crudUrl: 'Home/UpdateData',
adaptor: new UrlAdaptor(),
crossDomain: true
});
return(
<KanbanComponent id="kanban" keyField="Status" dataSource={data} cardSettings={{ contentField: "Summary", headerField: "Id" }}>
<ColumnsDirective>
<ColumnDirective headerText="To Do" keyField="Open" />
<ColumnDirective headerText="In Progress" keyField="InProgress" />
<ColumnDirective headerText="Testing" keyField="Testing" />
<ColumnDirective headerText="Done" keyField="Close" />
</ColumnsDirective>
</KanbanComponent>
);
}
ReactDOM.render(<App />, document.getElementById('kanban'));private NORTHWNDEntities db = new NORTHWNDEntities();
public ActionResult DataSource() {
var DataSource = db.Tasks.ToList();
return Json(DataSource, JsonRequestBehavior.AllowGet);
}
public ActionResult UpdateData(EditParams param) {
if (param.action == "insert" || (param.action == "batch" && param.added != null)) {
if (param.action == "insert") {
db.Tasks.Add(param.value);
} else {
foreach (var temp in param.added) {
db.Tasks.Add(temp);
}
}
}
if (param.action == "update" || (param.action == "batch" && param.changed != null)) {
if (param.action == "update") {
Task old = db.Tasks.Where(o => o.Id == param.value.Id).SingleOrDefault();
if (old != null) {
db.Entry(old).CurrentValues.SetValues(param.value);
}
} else {
foreach (var temp in param.changed) {
Task old = db.Tasks.Where(o => o.Id == temp.Id).SingleOrDefault();
if (old != null) {
db.Entry(old).CurrentValues.SetValues(temp);
}
}
}
}
if (param.action == "remove" || (param.action == "batch" && param.deleted != null)) {
if (param.action == "remove") {
int key = Convert.ToInt32(param.key);
db.Tasks.Remove(db.Tasks.Where(o => o.Id == key).SingleOrDefault());
} else {
foreach (var temp in param.deleted) {
db.Tasks.Remove(db.Tasks.Where(o => o.Id == temp.Id).SingleOrDefault());
}
}
}
db.SaveChanges();
return Json(param, JsonRequestBehavior.AllowGet);
}
public class EditParams {
public string key { get; set; }
public string action { get; set; }
public List<Tasks> added { get; set; }
public List<Tasks> changed { get; set; }
public List<Tasks> deleted { get; set; }
public Tasks value { get; set; }
}The
crudUrlis used to update the bulk data sent to the server-side. Multiple selections andsortByasIndexproperties are used forcrudUrlproperties to update the modified bulk data to the server-side.