Issue #1891💬 AnsweredOpened March 14, 2019by jwilson-lyonscg0 reactions

Can't create new button component

快速解答by jwilson-lyonscg

Okay so after some more experimentation it appears my component structure is correct, but my button block was not working correctly. So the button block was like this: When dragging this block into the canvas, this did not get recognized as a button component. However when I changed it to this: Then it works fine. Is...

Read full answer below ↓

Question

I'm having a hard time creating a new component for a <button> element. What am I missing? Is something bugged out here? Works fine if I change it to an <input> element:

comps.addType('button', {
        model: defaultModel.extend({
            defaults: Object.assign({}, defaultModel.prototype.defaults, {
                draggable: true,
                droppable: false,
                traits: [
                    'test'
                ]
            })
        },{
            isComponent: (el) => {
                if (el.tagName === 'BUTTON') {
                    return {type: 'button'}
                }
            },
        }),
    });

Answers (3)

jwilson-lyonscgMarch 14, 2019

Okay so after some more experimentation it appears my component structure is correct, but my button block was not working correctly. So the button block was like this:

window.editor.BlockManager.add('button', {
    attributes: {
        class: 'fa fa-cube'
    },
    category: 'basic',
    label: 'Button',
    content: {
        draggable: true,
        droppable: true,
        content: '<button type="button" class="btn btn-primary">Learn More</button>',
    }
});

When dragging this block into the canvas, this did not get recognized as a button component. However when I changed it to this:

window.editor.BlockManager.add('button', {
    attributes: {
        class: 'fa fa-cube'
    },
    category: 'basic',
    label: 'Button',
    content: '<button type="button" class="btn btn-primary">Learn More</button>',
});

Then it works fine. Is this a bug or is this by design? I can't find anything in the documentation about why it would work this way.

artfMarch 22, 2019

I think the problem here is a misunderstanding of content key. When you declare a block

editor.BlockManager.add('button-block', {
	// ...
    content: {
		type: 'button',
		droppable: false,
		attributes: { 
			title: 'Hello',  
			type: 'submit',
		},
    },
});

The content is for the Component, like a string o like an object. The string version of the example above would be:

editor.BlockManager.add('button-block', {
	// ...
    content: `<button data-gjs-droppable="false" type="submit" title="Hello"></button>`,
});

But when you use content inside a Component, it indicates the use of static content (eg. like the one used in RTE), so it won't be parsed by the editor and in the JSON it will be stored as a string. So this component object:

{
        draggable: true,
        droppable: true,
        content: '<button type="button" class="btn btn-primary">Learn More</button>',
    }

will generate this HTML

<div>
	<button type="button" class="btn btn-primary">Learn More</button>
</div>

where the button is not parsed and you won't be able to select it from the editor. If you want the button string be parsed by the editor, use this:

{
        draggable: true,
        droppable: true,
        components: '<button type="button" class="btn btn-primary">Learn More</button>',
    }

that after parser will become

{
        draggable: true,
        droppable: true,
        components: [
			{
				type: 'button',
				...
			}
		],
    }

So the HTML will be the same but the editor will see it as a component and not just a string

lock[bot]March 21, 2020

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Related Questions and Answers

Continue research with similar issue discussions.

Paid Plugins That Match This Issue

Curated by issue keywords and label relevance to help you ship faster.

View all plugins

Loading paid plugin recommendations...

Free option

Check the open-source GrapesJS plugins on GitHub or run a quick search in our free catalog.

Browse free plugins →
Premium option

Premium plugins ship with support, regular updates, and production-ready features — save days of integration work.

Browse premium plugins →

Related tutorials

In-depth guides on the same topic.

All tutorials →

Browse Plugin Categories

Jump directly to plugin category pages on the marketplace.