Item Drag & Drop - React List (2024)

import React, { useCallback, useState } from 'react';import List, { IItemDraggingProps, ItemDragging } from 'devextreme-react/list';import { plannedTasks, doingTasks } from './data.ts';const App = () => { const [plannedTasksState, setPlannedTasksState] = useState(plannedTasks); const [doingTasksState, setDoingTasksState] = useState(doingTasks); const onDragStart = useCallback<IItemDraggingProps['onDragStart']>((e) => { e.itemData = e.fromData === 'plannedTasks' ? plannedTasksState[e.fromIndex] : doingTasksState[e.fromIndex]; }, [plannedTasksState, doingTasksState]); const onAdd = useCallback<IItemDraggingProps['onAdd']>((e) => { const tasks = e.toData === 'plannedTasks' ? plannedTasksState : doingTasksState; const updatedTasks = [...tasks]; updatedTasks.splice(e.toIndex, 0, e.itemData); if (e.toData === 'plannedTasks') { setPlannedTasksState(updatedTasks); } else { setDoingTasksState(updatedTasks); } }, [setPlannedTasksState, setDoingTasksState, plannedTasksState, doingTasksState]); const onRemove = useCallback<IItemDraggingProps['onRemove']>((e) => { const tasks = e.fromData === 'plannedTasks' ? plannedTasksState : doingTasksState; const updatedTasks = [...tasks]; updatedTasks.splice(e.fromIndex, 1); if (e.fromData === 'plannedTasks') { setPlannedTasksState(updatedTasks); } else { setDoingTasksState(updatedTasks); } }, [setPlannedTasksState, setDoingTasksState, plannedTasksState, doingTasksState]); const onReorder = useCallback((e) => { if (e.fromData === e.toData) { const updateTasks = (tasks) => { const updatedTasks = [...tasks]; const [movedTask] = updatedTasks.splice(e.fromIndex, 1); updatedTasks.splice(e.toIndex, 0, movedTask); return updatedTasks; }; if (e.fromData === 'plannedTasks') { setPlannedTasksState((prevTasks) => updateTasks(prevTasks)); } else { setDoingTasksState((prevTasks) => updateTasks(prevTasks)); } } else { onRemove(e); onAdd(e); } }, [onAdd, onRemove]); return ( <div className="widget-container"> <List dataSource={plannedTasksState} keyExpr="id"> <ItemDragging allowReordering={true} group="tasks" data="plannedTasks" onDragStart={onDragStart} onAdd={onAdd} onRemove={onRemove} onReorder={onReorder}> </ItemDragging> </List> <List dataSource={doingTasksState} keyExpr="id"> <ItemDragging allowReordering={true} group="tasks" data="doingTasks" onDragStart={onDragStart} onAdd={onAdd} onRemove={onRemove} onReorder={onReorder}> </ItemDragging> </List> </div> );};export default App;

import React, { useCallback, useState } from 'react';import List, { ItemDragging } from 'devextreme-react/list';import { plannedTasks, doingTasks } from './data.js';const App = () => { const [plannedTasksState, setPlannedTasksState] = useState(plannedTasks); const [doingTasksState, setDoingTasksState] = useState(doingTasks); const onDragStart = useCallback( (e) => { e.itemData = e.fromData === 'plannedTasks' ? plannedTasksState[e.fromIndex] : doingTasksState[e.fromIndex]; }, [plannedTasksState, doingTasksState], ); const onAdd = useCallback( (e) => { const tasks = e.toData === 'plannedTasks' ? plannedTasksState : doingTasksState; const updatedTasks = [...tasks]; updatedTasks.splice(e.toIndex, 0, e.itemData); if (e.toData === 'plannedTasks') { setPlannedTasksState(updatedTasks); } else { setDoingTasksState(updatedTasks); } }, [setPlannedTasksState, setDoingTasksState, plannedTasksState, doingTasksState], ); const onRemove = useCallback( (e) => { const tasks = e.fromData === 'plannedTasks' ? plannedTasksState : doingTasksState; const updatedTasks = [...tasks]; updatedTasks.splice(e.fromIndex, 1); if (e.fromData === 'plannedTasks') { setPlannedTasksState(updatedTasks); } else { setDoingTasksState(updatedTasks); } }, [setPlannedTasksState, setDoingTasksState, plannedTasksState, doingTasksState], ); const onReorder = useCallback( (e) => { if (e.fromData === e.toData) { const updateTasks = (tasks) => { const updatedTasks = [...tasks]; const [movedTask] = updatedTasks.splice(e.fromIndex, 1); updatedTasks.splice(e.toIndex, 0, movedTask); return updatedTasks; }; if (e.fromData === 'plannedTasks') { setPlannedTasksState((prevTasks) => updateTasks(prevTasks)); } else { setDoingTasksState((prevTasks) => updateTasks(prevTasks)); } } else { onRemove(e); onAdd(e); } }, [onAdd, onRemove], ); return ( <div className="widget-container"> <List dataSource={plannedTasksState} keyExpr="id" > <ItemDragging allowReordering={true} group="tasks" data="plannedTasks" onDragStart={onDragStart} onAdd={onAdd} onRemove={onRemove} onReorder={onReorder} ></ItemDragging> </List> <List dataSource={doingTasksState} keyExpr="id" > <ItemDragging allowReordering={true} group="tasks" data="doingTasks" onDragStart={onDragStart} onAdd={onAdd} onRemove={onRemove} onReorder={onReorder} ></ItemDragging> </List> </div> );};export default App;

import React from 'react';import ReactDOM from 'react-dom';import App from './App.tsx';ReactDOM.render( <App />, document.getElementById('app'),);

export const doingTasks = [{ id: 1, text: 'Prepare 2019 Financial' }, { id: 2, text: 'Prepare 2019 Marketing Plan' }, { id: 3, text: 'Update Personnel Files' }, { id: 4, text: 'Review Health Insurance Options Under the Affordable Care Act' }];export const plannedTasks = [{ id: 5, text: 'New Brochures' }, { id: 6, text: '2019 Brochure Designs' }, { id: 7, text: 'Brochure Design Review' }, { id: 8, text: 'Website Re-Design Plan' }, { id: 9, text: 'Rollout of New Website and Marketing Brochures' }, { id: 10, text: 'Create 2018 Sales Report' }, { id: 11, text: 'Direct vs Online Sales Comparison Report' }, { id: 12, text: 'Review 2018 Sales Report and Approve 2019 Plans' }, { id: 13, text: 'Submit Signed NDA' }, { id: 14, text: 'Update Revenue Projections' }, { id: 15, text: 'Review Revenue Projections' }, { id: 16, text: 'Comment on Revenue Projections' }, { id: 17, text: 'Scan Health Insurance Forms' }, { id: 18, text: 'Sign Health Insurance Forms' }, { id: 19, text: 'Follow up with West Coast Stores' }, { id: 20, text: 'Follow up with East Coast Stores' }, { id: 21, text: 'Submit Refund Report for 2019 Recall' }, { id: 22, text: 'Give Final Approval for Refunds' }, { id: 23, text: 'Prepare Product Recall Report' }, { id: 24, text: 'Review Product Recall Report by Engineering Team' }, { id: 25, text: 'Review Training Course for any Omissions' }, { id: 26, text: 'Review Overtime Report' }, { id: 27, text: 'Submit Overtime Request Forms' }, { id: 28, text: 'Overtime Approval Guidelines' }, { id: 29, text: 'Create Report on Customer Feedback' }, { id: 30, text: 'Review Customer Feedback Report' }];

window.exports = window.exports || {};window.config = { transpiler: 'ts', typescriptOptions: { module: 'system', emitDecoratorMetadata: true, experimentalDecorators: true, jsx: 'react', }, meta: { 'react': { 'esModule': true, }, 'typescript': { 'exports': 'ts', }, 'devextreme/time_zone_utils.js': { 'esModule': true, }, 'devextreme/localization.js': { 'esModule': true, }, 'devextreme/viz/palette.js': { 'esModule': true, }, }, paths: { 'npm:': 'https://unpkg.com/', }, defaultExtension: 'js', map: { 'ts': 'npm:[email protected]/lib/plugin.js', 'typescript': 'npm:[email protected]/lib/typescript.js', 'react': 'npm:[email protected]/umd/react.development.js', 'react-dom': 'npm:[email protected]/umd/react-dom.development.js', 'prop-types': 'npm:[email protected]/prop-types.js', 'rrule': 'npm:[email protected]/dist/es5/rrule.js', 'luxon': 'npm:[email protected]/build/global/luxon.min.js', 'es6-object-assign': 'npm:[email protected]', 'devextreme': 'npm:[email protected]/cjs', 'devextreme-react': 'npm:[email protected]/cjs', 'jszip': 'npm:[email protected]/dist/jszip.min.js', 'devextreme-quill': 'npm:[email protected]/dist/dx-quill.min.js', 'devexpress-diagram': 'npm:[email protected]/dist/dx-diagram.js', 'devexpress-gantt': 'npm:[email protected]/dist/dx-gantt.js', '@devextreme/runtime': 'npm:@devextreme/[email protected]', 'inferno': 'npm:[email protected]/dist/inferno.min.js', 'inferno-compat': 'npm:inferno-compat/dist/inferno-compat.min.js', 'inferno-create-element': 'npm:[email protected]/dist/inferno-create-element.min.js', 'inferno-dom': 'npm:inferno-dom/dist/inferno-dom.min.js', 'inferno-hydrate': 'npm:[email protected]/dist/inferno-hydrate.min.js', 'inferno-clone-vnode': 'npm:inferno-clone-vnode/dist/inferno-clone-vnode.min.js', 'inferno-create-class': 'npm:inferno-create-class/dist/inferno-create-class.min.js', 'inferno-extras': 'npm:inferno-extras/dist/inferno-extras.min.js', 'devextreme-cldr-data': 'npm:[email protected]', // SystemJS plugins 'plugin-babel': 'npm:[email protected]/plugin-babel.js', 'systemjs-babel-build': 'npm:[email protected]/systemjs-babel-browser.js', // Prettier 'prettier/standalone': 'npm:[email protected]/standalone.js', 'prettier/parser-html': 'npm:[email protected]/parser-html.js', }, packages: { 'devextreme': { defaultExtension: 'js', }, 'devextreme-react': { main: 'index.js', }, 'devextreme/events/utils': { main: 'index', }, 'devextreme/localization/messages': { format: 'json', defaultExtension: 'json', }, 'devextreme/events': { main: 'index', }, 'es6-object-assign': { main: './index.js', defaultExtension: 'js', }, }, packageConfigPaths: [ 'npm:@devextreme/*/package.json', 'npm:@devextreme/[email protected]/inferno/package.json', ], babelOptions: { sourceMaps: false, stage0: true, react: true, },};System.config(window.config);

import React from 'react';import ReactDOM from 'react-dom';import App from './App.js';ReactDOM.render(<App />, document.getElementById('app'));

export const doingTasks = [ { id: 1, text: 'Prepare 2019 Financial' }, { id: 2, text: 'Prepare 2019 Marketing Plan' }, { id: 3, text: 'Update Personnel Files' }, { id: 4, text: 'Review Health Insurance Options Under the Affordable Care Act' },];export const plannedTasks = [ { id: 5, text: 'New Brochures' }, { id: 6, text: '2019 Brochure Designs' }, { id: 7, text: 'Brochure Design Review' }, { id: 8, text: 'Website Re-Design Plan' }, { id: 9, text: 'Rollout of New Website and Marketing Brochures' }, { id: 10, text: 'Create 2018 Sales Report' }, { id: 11, text: 'Direct vs Online Sales Comparison Report' }, { id: 12, text: 'Review 2018 Sales Report and Approve 2019 Plans' }, { id: 13, text: 'Submit Signed NDA' }, { id: 14, text: 'Update Revenue Projections' }, { id: 15, text: 'Review Revenue Projections' }, { id: 16, text: 'Comment on Revenue Projections' }, { id: 17, text: 'Scan Health Insurance Forms' }, { id: 18, text: 'Sign Health Insurance Forms' }, { id: 19, text: 'Follow up with West Coast Stores' }, { id: 20, text: 'Follow up with East Coast Stores' }, { id: 21, text: 'Submit Refund Report for 2019 Recall' }, { id: 22, text: 'Give Final Approval for Refunds' }, { id: 23, text: 'Prepare Product Recall Report' }, { id: 24, text: 'Review Product Recall Report by Engineering Team' }, { id: 25, text: 'Review Training Course for any Omissions' }, { id: 26, text: 'Review Overtime Report' }, { id: 27, text: 'Submit Overtime Request Forms' }, { id: 28, text: 'Overtime Approval Guidelines' }, { id: 29, text: 'Create Report on Customer Feedback' }, { id: 30, text: 'Review Customer Feedback Report' },];

<!DOCTYPE html><html lang="en"> <head> <title>DevExtreme Demo</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/24.1.5/css/dx.light.css" /> <link rel="stylesheet" type="text/css" href="styles.css" /> <script src="https://unpkg.com/[email protected]/client/shim.min.js"></script> <script src="https://unpkg.com/[email protected]/dist/system.js"></script> <script type="text/javascript" src="config.js"></script> <script type="text/javascript"> System.import("./index.tsx"); </script> </head> <body class="dx-viewport"> <div class="demo-container"> <div id="app"></div> </div> </body></html>

.widget-container { display: flex;}.widget-container > * { height: 400px; width: 50%; padding: 10px;}.dx-scrollview-content { min-height: 380px;}

Item Drag & Drop - React List (2024)
Top Articles
Cruise Currencies, What Will I Need To Take? - Vision Cruise
Frontiers | Climate change and the politicization of ESG in the US
English Bulldog Puppies For Sale Under 1000 In Florida
Katie Pavlich Bikini Photos
Gamevault Agent
Pieology Nutrition Calculator Mobile
Hocus Pocus Showtimes Near Harkins Theatres Yuma Palms 14
Hendersonville (Tennessee) – Travel guide at Wikivoyage
Compare the Samsung Galaxy S24 - 256GB - Cobalt Violet vs Apple iPhone 16 Pro - 128GB - Desert Titanium | AT&T
Vardis Olive Garden (Georgioupolis, Kreta) ✈️ inkl. Flug buchen
Craigslist Dog Kennels For Sale
Things To Do In Atlanta Tomorrow Night
Non Sequitur
Crossword Nexus Solver
How To Cut Eelgrass Grounded
Pac Man Deviantart
Alexander Funeral Home Gallatin Obituaries
Energy Healing Conference Utah
Geometry Review Quiz 5 Answer Key
Hobby Stores Near Me Now
Icivics The Electoral Process Answer Key
Allybearloves
Bible Gateway passage: Revelation 3 - New Living Translation
Yisd Home Access Center
Pearson Correlation Coefficient
Home
Shadbase Get Out Of Jail
Gina Wilson Angle Addition Postulate
Celina Powell Lil Meech Video: A Controversial Encounter Shakes Social Media - Video Reddit Trend
Walmart Pharmacy Near Me Open
Marquette Gas Prices
A Christmas Horse - Alison Senxation
Ou Football Brainiacs
Access a Shared Resource | Computing for Arts + Sciences
Vera Bradley Factory Outlet Sunbury Products
Pixel Combat Unblocked
Movies - EPIC Theatres
Cvs Sport Physicals
Mercedes W204 Belt Diagram
Mia Malkova Bio, Net Worth, Age & More - Magzica
'Conan Exiles' 3.0 Guide: How To Unlock Spells And Sorcery
Teenbeautyfitness
Where Can I Cash A Huntington National Bank Check
Topos De Bolos Engraçados
Sand Castle Parents Guide
Gregory (Five Nights at Freddy's)
Grand Valley State University Library Hours
Hello – Cornerstone Chapel
Stoughton Commuter Rail Schedule
Nfsd Web Portal
Selly Medaline
Latest Posts
Article information

Author: Rev. Porsche Oberbrunner

Last Updated:

Views: 6633

Rating: 4.2 / 5 (53 voted)

Reviews: 92% of readers found this page helpful

Author information

Name: Rev. Porsche Oberbrunner

Birthday: 1994-06-25

Address: Suite 153 582 Lubowitz Walks, Port Alfredoborough, IN 72879-2838

Phone: +128413562823324

Job: IT Strategist

Hobby: Video gaming, Basketball, Web surfing, Book restoration, Jogging, Shooting, Fishing

Introduction: My name is Rev. Porsche Oberbrunner, I am a zany, graceful, talented, witty, determined, shiny, enchanting person who loves writing and wants to share my knowledge and understanding with you.