jquery - Draggable item in custom gutenberg block

admin2025-01-08  3

I'm developing some custom blocks in the new Gutenberg editor experience, and I'm struggle to understand how to use some build-in components, mostly the Draggable components.

What I would like to achieve is a list of items (let's say many li in a ul) and I want them to be orderable with a drag & drop feature.

Here is my code:

import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
import { Draggable, Dashicon } from '@wordpress/components';

import './style.scss';
import './editor.scss';

registerBlockType( 'namespace/my-custom-block', 
{
    title: __( 'Custom block', 'namespace'),
    description: __( 'Description of the custom block', 'namespace' ),
    category: 'common',
    icon: 'clipboard',
    keywords: [
    __( 'list', 'namespace' ),
    __( 'item', 'namespace' ),
    __( 'order', 'namespace' )
    ],
    supports: {
    html: false,
    multiple: false,
    },
    attributes: {
        items: {
            type: 'array',
            default: [ 'One' ,'Two' ,'Tree' ,'Four' ,'Five' ,'Six' ,'Seven' ,'Eight' ,'Nine' ,'Ten' ]
        }
    },
    edit: props => {
    return (
        <ul>
        { props.attributes.items.map( (itemLabel, id) => (
            <li id={ `li_${id}` } draggable>
            <Draggable
                elementId={ `li_${id}` }
                transferData={ {} }>
                {
                ({ onDraggableStart, onDraggableEnd }) => (
                    <Dashicon
                    icon="move"
                    onDragStart={ onDraggableStart }
                    onDragEnd={ onDraggableEnd }
                    draggable
                    />
                )
                }
            </Draggable>
            { itemLabel }
            </li>
        ))
        }
        </ul>
    )
    },
    save: () => {
    // Return null to be rendered on the server
    return null;
    }
}
)

On the backend side it is correctly rendered but the items are not draggable

Unfortunately the gutenberg developer handbook doesn't give much info / and I'm not seeing how should I do it.

Thanks and cheers

I'm developing some custom blocks in the new Gutenberg editor experience, and I'm struggle to understand how to use some build-in components, mostly the Draggable components.

What I would like to achieve is a list of items (let's say many li in a ul) and I want them to be orderable with a drag & drop feature.

Here is my code:

import { __ } from '@wordpress/i18n';
import { registerBlockType } from '@wordpress/blocks';
import { Draggable, Dashicon } from '@wordpress/components';

import './style.scss';
import './editor.scss';

registerBlockType( 'namespace/my-custom-block', 
{
    title: __( 'Custom block', 'namespace'),
    description: __( 'Description of the custom block', 'namespace' ),
    category: 'common',
    icon: 'clipboard',
    keywords: [
    __( 'list', 'namespace' ),
    __( 'item', 'namespace' ),
    __( 'order', 'namespace' )
    ],
    supports: {
    html: false,
    multiple: false,
    },
    attributes: {
        items: {
            type: 'array',
            default: [ 'One' ,'Two' ,'Tree' ,'Four' ,'Five' ,'Six' ,'Seven' ,'Eight' ,'Nine' ,'Ten' ]
        }
    },
    edit: props => {
    return (
        <ul>
        { props.attributes.items.map( (itemLabel, id) => (
            <li id={ `li_${id}` } draggable>
            <Draggable
                elementId={ `li_${id}` }
                transferData={ {} }>
                {
                ({ onDraggableStart, onDraggableEnd }) => (
                    <Dashicon
                    icon="move"
                    onDragStart={ onDraggableStart }
                    onDragEnd={ onDraggableEnd }
                    draggable
                    />
                )
                }
            </Draggable>
            { itemLabel }
            </li>
        ))
        }
        </ul>
    )
    },
    save: () => {
    // Return null to be rendered on the server
    return null;
    }
}
)

On the backend side it is correctly rendered but the items are not draggable

Unfortunately the gutenberg developer handbook doesn't give much info https://wordpress.org/gutenberg/handbook/designers-developers/developers/components/draggable/ and I'm not seeing how should I do it.

Thanks and cheers

Share Improve this question edited Nov 15, 2019 at 11:27 tru.d 1861 gold badge1 silver badge17 bronze badges asked Dec 14, 2018 at 21:20 KuuakKuuak 811 gold badge1 silver badge7 bronze badges 3
  • I don't know the answer to your question, but an alternative might instead be to have child blocks and whitelist a second block type, then you could drag and drop them via the GB editor controls instead – Tom J Nowell Commented Dec 14, 2018 at 23:31
  • Adding extra drag inside a block might create conflicts. Possibly the drop area of the block overlays the block content when a drag starts. Also, remove the draggable property from the <li>. – Alvaro Commented Dec 14, 2018 at 23:46
  • noting that since this was written, list blocks themselves and others in WP core are transitioning to being child blocks, with the ability to drag and drop being a new selling point of this. – Tom J Nowell Commented Oct 5, 2022 at 13:42
Add a comment  | 

2 Answers 2

Reset to default 0

If you need to make something drag and drop that appears inside your block in the main content area, then you should use child blocks to implement that, and the <InnerBlocks/> component. You can then force the inner blocks so that they can only be your new child block type.

For example we could have a kuuak/my-custom-block block, and each draggable item would be a kuuak/my-custom-block-item. Then you could use this to allow items to be inserted and sorted, but only your item block, nothing else:

const ALLOWED_BLOCKS = [ 'kuuak/my-custom-block-item' ];
//...
<InnerBlocks allowedBlocks={ ALLOWED_BLOCKS } />;

You can also force it so that item blocks can't be used anywhere else block type when registering:

"parent": [ "kuuak/my-custom-block" ],

This pattern is used in a lot of WordPress core blocks, e.g. a columns block that can only contain "column" blocks, the new gallery blocks that act as containers for individual image blocks, carousels, etc

Further reading on nested/inner blocks: https://developer.wordpress.org/block-editor/how-to-guides/block-tutorial/nested-blocks-inner-blocks/

Use react-sortable-hoc Draggable is lacking documentation and I did not had the time to dig into it. But the above is for you. I used it to create the sidebar Entry Content/Primary Sidebar control - used to reorder my theme content/sidebar!

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1736267149a1176.html

最新回复(0)