GrapesJS / grapesjs

Free and Open source Web Builder Framework. Next generation tool for building templates without coding
https://grapesjs.com
BSD 3-Clause "New" or "Revised" License
22.36k stars 4.05k forks source link

QUESTION: Prevent/Disable Custom Blocks from being dropped inside other Custom Blocks #3258

Closed stljeff1 closed 3 years ago

stljeff1 commented 3 years ago

Hello,

I have a custom component, let's call it a Section Block. I want to prevent the user from dropping Section Blocks inside other Section Blocks. Is that possible?

Ref: https://grapesjs.com/docs/modules/Components.html#define-custom-component-type

I am aware of the draggable/droppable options that I can define on new component types. My understanding of these options is that they are inclusive.

...
draggable: 'form, form *', // Can be dropped only inside `form` elements
...

Is there a way to make draggable exclusive, where I say, "this block can be dropped anywhere EXCEPT [[component type]]"?

artf commented 3 years ago

You can use :not() selector, eg. :not(.except-this-class)

stljeff1 commented 3 years ago

Thanks @artf . This solution works, mostly. Now I am encountering a new problem where some placeholder text is disappearing.

On some elements inside my blocks, I'll have an HTML element with a text node, then some other nested html element. An example would be a link tag containing an icon.

<a href="#">Click Me <i class="fa fa-chevron-right"></i></a>

When I add the draggable option to the model of my component, HTML elements inside the block similar to the A tag above will lose their text node. If I wrap these text nodes in something like a span tag, the text will stay. Examples of elements that don''t change:

<h1>I'm a Lonely textnode</h1>
<a href="#><span>this textnode is safe</span><i class="fa fa-chevron-right"></i></a>

Do you know of anything that will cause text nodes to disappear if they appear inside a container with other elements?

Here is how I am creating my custom component:


        editor.DomComponents.addType('MySectionBlock', {
            model: editor.DomComponents.getType('default').model.extend({
                draggable: ':not(.my-section-block)'
            }),
            view: editor.DomComponents.getType('default').view.extend({
                init() {
                    this.listenTo(this.model, 'active', this.act());
                },
                act() {
                        // do stuff to manipulate the view

                },
            })
        });

My apologies if this new issue is vague. I am still troubleshooting, and very confused how this draggable config option can affect my component's view. Do you think I am somehow deleting these text nodes after I initiate my component's view?

Thanks again.

artf commented 3 years ago

You're defining the component with the old API, which requires other stuff to work properly and that might be the cause of the issue (I've tried on my side and everything works as expected). Please check here for the correct API https://grapesjs.com/docs/modules/Components.html#define-custom-component-type