'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

enter image description here

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 as react-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