'Custom react-admin drag & drop list
It can't drag. What is wrong with it?
I'm using react-sortable-hoc with material-ui to custom react-admin list page with drag & drop sortable.
Demo : https://codesandbox.io/s/vibrant-visvesvaraya-4k3gs
Source code: https://github.com/tangbearrrr/poc-ra-sort-drag/tree/main
Solution 1:[1]
As I checked you are getting data
from the props and in props
there is no data field exists, so the error is coming from there
Here is the all props list
Solution 2:[2]
The sortable method you are using is from react-sortable-hoc, which adds huge complexity to react-admin.
Not so fast, I have run out of attempts trying to debug your code and come up with another solution works just fine but not so ideal, is to use sortablejs
:
yarn add sortablejs
yarn add @types/sortablejs --dev
Do not mess up with
react-sortablejs
, this also applies the same complexity level asreact-sortable-hoc
.
Let's use your cmsLanguage as an example, with changes to use Datagrid
instead.
Just be reminded that this working solution needs several retries on null el
(e.g. your data is fetching, slow network speed, etc). The code below has 3 retries, 1500 milliseconds per each retry. The initialisation will stop after 3 attempts.
import {Datagrid, ShowButton, TextField} from "react-admin";
import * as React from "react";
import MenuIcon from '@mui/icons-material/Menu';
import {useEffect} from "react";
import Sortable from 'sortablejs';
const LanguageList = () => {
// This will run the effect after every render
useEffect(() => {
// https://github.com/SortableJS/Sortable
const retries = 3;
const millisecords = 1500;
let attempts = 0;
const retrySortable = () => {
const el = document.querySelector('#sortable-list tbody');
if (!el) {
if (++attempts >= retries) {
console.log(`cannot initialise sortable after ${retries} retries.`);
} else {
setTimeout(() => retrySortable(), millisecords);
}
} else {
// @ts-ignore
new Sortable(el, {
handle: ".handle",
draggable: "tr",
animation: 150, // ms, animation speed moving items when sorting, `0` — without animation
easing: "cubic-bezier(1, 0, 0, 1)", // Easing for animation. Defaults to null. See https://easings.net/ for examples.
// Element dragging ended
onEnd: (evt) => {
// @ts-ignore
const reorderedList: string[] = [];
const list = document.querySelectorAll('#sortable-list tbody td.column-name span');
[].forEach.call(list, function (span: Element) {
reorderedList.push(span.innerHTML);
});
console.log(JSON.stringify(reorderedList));
console.log(evt);
},
});
}
}
retrySortable();
}, []);
return (
<section id="sortable-list">
<Datagrid>
<MenuIcon sx={{cursor: "pointer"}} className="handle"/>
<TextField source="name"/>
<ShowButton/>
</Datagrid>
</section>
);
};
export default LanguageList;
When someone has a request for a demo, I will draw some time to make this a GitHub repo for better reference.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Nisharg Shah |
Solution 2 |