Search results

Drag and Drop list items in React ListView component

22 Oct 2021 / 2 minutes to read

In ListView component, we don’t have drag and drop support. But we can achieve this requirement using TreeView component with ListView appearance.

Drag and Drop in TreeView component was enabled by setting allowDragAndDrop to true.

Copied to clipboard
        <TreeViewComponent id='treeview'
                dataSource={this.data}
                allowDragAndDrop = {true}
                fields= {this.field} >
        </TreeViewComponent>

The TreeView component is used to represent hierarchical data in a tree like structure. So, list items in TreeView can be dropped to child of target element. we can prevent this behaviour by cancelling the nodeDragStop and nodeDragging events.

Copied to clipboard
onDragStop(args: DragAndDropEventArgs) {
    //Block the Child Drop operation in TreeView
   let  draggingItem: HTMLCollection = document.getElementsByClassName("e-drop-in");
    if (draggingItem.length == 1) {
        draggingItem[0].classList.add('e-no-drop');
        args.cancel = true;
    }
}

render() {
        return (
        <TreeViewComponent id='treeview'
                dataSource={this.data}
                allowDragAndDrop = {true}
                nodeDragging = {this.onDragStop.bind(this)}
                nodeDragStop = {this.onDragStop.bind(this)}
                fields= {this.field} >
        </TreeViewComponent>
        )
    }
Copied to clipboard
onDragStop(args, DragAndDropEventArgs);
{
    //Block the Child Drop operation in TreeView
    let draggingItem = document.getElementsByClassName("e-drop-in");
    if (draggingItem.length == 1) {
        draggingItem[0].classList.add('e-no-drop');
        args.cancel = true;
    }
}
render();
{
    return (<TreeViewComponent id='treeview' dataSource={this.data} allowDragAndDrop={true} nodeDragging={this.onDragStop.bind(this)} nodeDragStop={this.onDragStop.bind(this)} fields={this.field}>
        </TreeViewComponent>);
}

In the below sample, we have rendered draggable list items.

Source
Preview
App.tsx
index.tsx
index.html
index.css
App.jsx
index.jsx
Copied to clipboard
Copied to clipboard
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { TreeViewComponent } from '@syncfusion/ej2-react-navigations';
import {DragAndDropEventArgs } from '@syncfusion/ej2-navigations';

export default class App extends React.Component<{}, {}> {
  //Define an array of JSON data
  public data: any[] = [
    { text: "Hennessey Venom", id: "list-01" },
    { text: "Bugatti Chiron", id: "list-02" },
    { text: "Bugatti Veyron Super Sport", id: "list-03" },
    { text: "SSC Ultimate Aero", id: "list-04" },
    { text: "Koenigsegg CCR", id: "list-05" },
    { text: "McLaren F1", id: "list-06" },
    { text: "Aston Martin One- 77", id: "list-07" },
    { text: "Jaguar XJ220", id: "list-08" },
    { text: "McLaren P1", id: "list-09" },
    { text: "Ferrari LaFerrari", id: "list-10" }
  ];

  public field: object = { dataSource: this.data, id: "id", text: "text" };

  onDragStop(args: DragAndDropEventArgs) {
    //Block the Child Drop operation in TreeView
    let draggingItem: HTMLCollection = document.getElementsByClassName("e-drop-in");
    if (draggingItem.length == 1) {
      draggingItem[0].classList.add("e-no-drop");
      args.cancel = true;
    }
  }

  render() {
    return (
      <TreeViewComponent
        id="treeview"
        allowDragAndDrop={true}
        nodeDragging={this.onDragStop.bind(this) as any}
        nodeDragStop={this.onDragStop.bind(this) as any}
        fields={this.field}
      />
    );
  }
}
ReactDOM.render(<App />, document.getElementById('element'));
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Syncfusion React ListView</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Essential JS 2 for React Components" />
    <meta name="author" content="Syncfusion" />
    <link href="//cdn.syncfusion.com/ej2/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/ej2-react-navigations/styles/material.css" rel="stylesheet" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
    <div id='element'>
        <div id='loader'>Loading....</div>
    </div>
</body>

</html>
Copied to clipboard
#loader {
color: #008cff;
height: 40px;
width: 30%;
position: absolute;
font-family: 'Helvetica Neue','calibiri';
font-size: 14px;
top: 45%;
left: 45%;
}

#element{
  display: block;
  max-width: 280px;
  margin: auto;
  border: 1px solid #dddddd;
  border-radius: 3px;
}

#treeview.e-treeview .e-ul {
  padding: 0;
}

#treeview.e-treeview .e-list-item {
  padding: 0 16px;
}

#treeview.e-treeview .e-text-content {
  padding: 0;
}

#treeview.e-treeview .e-fullrow {
  height: 36px;
}

#treeview.e-treeview .e-list-text {
  line-height: 34px;
}

#treeview.e-treeview .e-list-item:last-child {
  margin-bottom: 9px;
}

#treeview.e-treeview .e-list-item:first-child {
  margin-top: 9px;
}
Copied to clipboard
Copied to clipboard
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { TreeViewComponent } from '@syncfusion/ej2-react-navigations';
export default class App extends React.Component {
    constructor() {
        super(...arguments);
        //Define an array of JSON data
        this.data = [
            { text: "Hennessey Venom", id: "list-01" },
            { text: "Bugatti Chiron", id: "list-02" },
            { text: "Bugatti Veyron Super Sport", id: "list-03" },
            { text: "SSC Ultimate Aero", id: "list-04" },
            { text: "Koenigsegg CCR", id: "list-05" },
            { text: "McLaren F1", id: "list-06" },
            { text: "Aston Martin One- 77", id: "list-07" },
            { text: "Jaguar XJ220", id: "list-08" },
            { text: "McLaren P1", id: "list-09" },
            { text: "Ferrari LaFerrari", id: "list-10" }
        ];
        this.field = { dataSource: this.data, id: "id", text: "text" };
    }
    onDragStop(args) {
        //Block the Child Drop operation in TreeView
        let draggingItem = document.getElementsByClassName("e-drop-in");
        if (draggingItem.length == 1) {
            draggingItem[0].classList.add("e-no-drop");
            args.cancel = true;
        }
    }
    render() {
        return (<TreeViewComponent id="treeview" allowDragAndDrop={true} nodeDragging={this.onDragStop.bind(this)} nodeDragStop={this.onDragStop.bind(this)} fields={this.field}/>);
    }
}
ReactDOM.render(<App />, document.getElementById('element'));