Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QUESTIONS] Custom Component disappear on Save (Vue.js) #2690

Closed
adamwpe opened this issue Mar 30, 2020 · 9 comments
Closed

[QUESTIONS] Custom Component disappear on Save (Vue.js) #2690

adamwpe opened this issue Mar 30, 2020 · 9 comments

Comments

@adamwpe
Copy link

adamwpe commented Mar 30, 2020

Hi All,

I'm trying to test adding some custom Vue.js components to the block manager, and at first appearance, all is well - it renders correctly and vue components are responsive.

But if I save the template, and reload my page, and supply the storageManager with 'gjs-style', 'gjs-components', 'gjs-html', 'gjs-css'.

The custom component no longer renders. It appears the the storageManager removes any script tags???? As if I check my REST GET request, 'gjs-html' does contain the <script> tag.

Before Saving:

before

After Reloading Loading:
after

Not too sure something is wrong with my component:

`
editor.BlockManager.add("vueApp", {
label: "Vue App",
category: 'Basic',
id: "default-vue-app",
content: {
script: function() {

                const app1El = document.createElement("div");
                app1El.id = 'app';

                const app1Script = document.createElement("script");
                app1Script.type = "text/javascript";
                app1Script.src = "http://[::1]/assets/vue/vueApp.js";

                this.appendChild(app1El);
                this.appendChild(app1Script);
            },
            traits: [
                {
                    type: 'text',
                    label: 'Nice',
                    name: 'custom_att',
                    value: 'Who knows',
                }
            ]
        }
    });

`

Have anyone tried using Vue.js components?

@adamwpe adamwpe changed the title [QUESTIONS] Custom Component disappear on reload (Vue.js) [QUESTIONS] Custom Component disappear on Save (Vue.js) Mar 31, 2020
@mcottret
Copy link

mcottret commented Apr 1, 2020

Hi @adamwpe !

Script tag importing is disabled by the default editor configuration, which explains why your scripts tags are stripped out by the HTML Parser, setting the allowScripts editor configuration option to true should solve the issue, eg:

grapesjs.init({
    // [...]
    allowScripts: true,
    // [...]
});

Hope this helps :)

@adamwpe
Copy link
Author

adamwpe commented Apr 1, 2020

Hi @mcottret

Thanks for the reply, but it was already set to true, forgot about that variable :(

This is my example init:


// Initialise the editor
var editor = grapesjs.init({
    height: '100%',
    noticeOnUnload: 1,
    allowScripts: true,
    container : '#gjs',
    avoidInlineStyle: true,
    fromElement: true,
    jsInHtml: true,
    plugins: ['gjs-preset-webpage'],
    storageManager: {
        type: 'remote',
        id: 'gjs-',
        autosave: true,
        autoload: true,
        storeComponents: true,
        contentTypeJson: true,
        stepsBeforeSave: 1,
        urlStore: '', 
        urlLoad: '/stores/get_store_page_data?store_page_data_id=<?php echo $id; ?>'
    },
    canvas: {
        scripts: ['https://cdn.jsdelivr.net/npm/vue/dist/vue.js'],
        styles: ['/../../../assets/css/main.css',
                 '/../../../assets/css/default.css',
                 'https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css'],
    },
    assetManager: {
        upload: '/clients/post_upload_gallery_image',
        uploadName: 'attachment',
        autoAdd: 1,
        dropzone: 0,
        params: {
              token: '<?php echo $this->security->get_csrf_hash() ?>'
        },
        assets: []
    },
    styleManager: {
        clearProperties: true,
    },
    pluginsOpts: {
        'gjs-preset-webpage': {
            formsOpts: false,
            countdownOpts: false,
            textExtra: 'Rotation',
            textTypography: 'Content'
        }
    }
});

Interestingly, If I change the component script from an object to a string:

image

It works!?!

Instead of:

image

Is that expected behavior? If so, what's the workaround (Apart from keeping it a string :))?

Thanks again for the reply 👍

@mcottret
Copy link

mcottret commented Apr 1, 2020

I don't know, according to the docs both approaches should be valid so that might be a bug. I'll try looking into it, unless someone finds an answer in the meantime.

Cheers !

@pouyamiralayi
Copy link

pouyamiralayi commented Apr 2, 2020

@adamwpe i believe you are not using the latest version!

@adamwpe
Copy link
Author

adamwpe commented Apr 2, 2020

@artf
Copy link
Member

artf commented Apr 2, 2020

The script property is not stored in the JSON, so you have to create a custom component. I know that this is how is indicated in docs, but I'd never found time to update it 😞

@artf artf closed this as completed Apr 2, 2020
@adamwpe
Copy link
Author

adamwpe commented Apr 2, 2020

@artf Sorry, not too sure what you mean that it's stored in the JSON. What do I need to do differently?

Do I need to append the canvas like this?

// Append components directly to the canvas
editor.addComponents(`<div>
  <img src="https://path/image" />
  <span title="foo">Hello world!!!</span>
</div>`);

or something like this (If so, where do I put the content?):


editor.DomComponents.addType('vue_test', {
            model: dModel.extend({
                init() {
                    this.listenTo(this, 'change:attributes', this.reRender);
                },
                removed() {

                },
                defaults: Object.assign({}, dModel.prototype.defaults, {
                    removable: true,
                    draggable: true,
                    droppable: true,
                    badgable: true,
                    stylable: true,
                    highlightable: true,
                    copyable: false,
                    resizable: false,
                    editable: false,
                    hoverable: true
                }),
                reRender() {
                    this.view.render();
                }
            }, {
                isComponent: function(el) {

                    if(el.tagName === 'vue_test')
                        return {type: 'vue_test'};
                }
            }),
            view: dView.extend({

                events: {

                }
            })
        });

@pouyamiralayi
Copy link

pouyamiralayi commented Apr 2, 2020

@adamwpe we had something like this in the past i apologize for not seeing it through!
go like this:

editor.DomComponents.addType('your-type', {
    model:{
        isComponent: el => {},
        defaults:{
            script:function(){},
        },
    }
})

there is no need to extend from dView & dModel in the latest versions.
and for the vue js integration please notice that the internal structure of your vue component would not be detected by grapesjs because there is no model generated for it! if you had any chance to overcome this scenario please let us know!
Cheers!

@adamwpe
Copy link
Author

adamwpe commented Apr 2, 2020

@pouyamiralayi

Thanks for that, pointed me in the right direction - so he is an example that works for me for rending a Vue Component and it will load back in :), but sure may be useful for someone else:


     editor.DomComponents.addType('vue_example', {
            model: {
                init() {

                    if (typeof this.getAttributes()['custom_att'] === "undefined")
                        this.addAttributes({'custom_att': 'default'});

                    // Onload, get the latest links
                    if (this.getTrait('custom_att') === undefined)
                        this.getTrait('custom_att').set('default');

                    this.getTrait('custom_att').set('default');

                    this.listenTo(this, 'change:attributes', this.reRender);

                },
                removed() {

                },
                defaults: {
                    removable: true,
                    draggable: true,
                    droppable: true,
                    badgable: true,
                    stylable: true,
                    highlightable: true,
                    copyable: false,
                    resizable: false,
                    editable: false,
                    hoverable: true,
                    traits: [
                        {
                            type: 'text',
                            label: 'Nice',
                            name: 'custom_att'
                        }
                    ],
                    script: function(){

                        const app1El = document.createElement("div");
                        app1El.id = 'app';

                        const app1Script = document.createElement("script");
                        app1Script.type = "text/javascript";
                        app1Script.src = "http://[::1]/assets/vue/vueApp.js";

                        this.appendChild(app1El);
                        this.appendChild(app1Script);

                    }
                },
                reRender() {
                    this.view.render();
                }
            },
            isComponent: function (el) {

                if (el.tagName === 'vue_example')
                    return {type: 'vue_example'};
            }

        });

        editor.BlockManager.add('vue_example', {
            id: 'vue_example',
            label: 'Vue Test',
            category: 'Vue',
            content: {
                tagName: 'vue_test',
                type: 'vue_example',
                editable: false
            }
        });

Thanks for the help everyone!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants