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]: New toolbar button works only for new added components and not for existing ones #3044

Closed RJCAM closed 4 years ago

RJCAM commented 4 years ago

Hi everybody, can somebody explain me please why when I create a new custom toolbar button this button shows only when I add a new component and not an existing one even this components are the same. I was thinking that might be something about the editor initiation that I'm not including. @artf What am I missing to make it work on init? Here is an example of how I'm adding the button.

const scriptTypesSupport = ['default','wrapper','text','textnode','image','video','svg','link'];
scriptTypesSupport && scriptTypesSupport.forEach(type => {
    const typeOpt = dc.getType(type).model;
    dc.addType(type, {
        model: {
            initToolbar() {
                typeOpt.prototype.initToolbar.apply(this, arguments);
                const tb = this.get('toolbar');
                const tbExists = tb.some(item => item.command === 'edit-component');

                if (!tbExists) {
                    tb.unshift({ // unshift to be the first and push to be the last
                        command: 'edit-component',
                        label: '<i class="fa fa-code"></i>',
                    });
                    this.set('toolbar', tb);
                }
            }
        }
    });
})

It works perfectly but like I said only for new components added and not for existing ones (example, if I init the editor with some code inside the gjs container the components won't have this new option in the toolbar) Above you can see when I add a second link the toolbar have the new button (pencil) but the existing one doens't. chrome-capture

Ju99ernaut commented 4 years ago

Probably the editor doesn't change a component during runtime when it's model is changed, so the component on the canvas was created before the model was modified therefore it wont show the changes to the toolbar.

RJCAM commented 4 years ago

Thanks for your response @Ju99ernaut, any ideas of how can I change them during runtime? I think It can work if I make those changes in the core but I was thinking in make some plugins with this type of functions and this way we can't make it work in external plugins. So it has to be after init (I think...)

Ju99ernaut commented 4 years ago

I've gotten around this by loading the canvas after loading all components and component modifications, but I guess depending on storage setup running editor.load() might fix that.

RJCAM commented 4 years ago

Ok, thanks @Ju99ernaut I will try that too

artf commented 4 years ago

The right way is to put your code in a plugin which will be loaded before component creation.

but I was thinking in make some plugins with this type of functions and this way we can't make it work in external plugins

You can load one plugin inside another is you want

import otherPlugin from 'grapesjs-some-plugin';

export default (editor, config) => {
  otherPlugin(editor);
  // ...
}