Issue #1432Opened September 17, 2018by JulyanoF2 reactions

[BUG] Custom DomComponent & Block let all elements duplicated

Question

I created a Custom Block:

bm.add('imagemLink', {
    label: 'Imagem Link',
    content: {
        activeOnRender: 1,
        droppable: false,
        type: 'imagemLink',
        content: '<a title="" link=""><img src="img/model.png"></img></a>'
    }
});

and a Custom DomComponent:

domComps.addType('imagemLink', {
  // Define the Model
  model: defaultType.model.extend({
        defaults: {
            tagName: "div",
            type: "",
            name: "",
            removable: !0,
            draggable: !0,
            droppable: !0,
            badgable: !0,
            stylable: !0,
            "stylable-require": "",
            unstylable: "",
            highlightable: !0,
            copyable: 0,
            resizable: !1,
            editable: !0,
            layerable: !0,
            selectable: !0,
            hoverable: !0,
            void: !1,
            state: "",
            status: "",
            content: "",
            icon: "",
            style: "",
            attributes: "",
            classes: "",
            script: "",
            traits: ["id", "title"],
            propagate: "",
            toolbar: null
        },
  }),
  view: defaultType.view.extend({
            events: {
            'click': function(){
                var openSmBtn = editor.Panels.getButton('views', 'optionsBlock');
                openSmBtn.set('active', 1);
            },
            'dblclick': function(){
                editor.select(this.model);
                selecionado = this.model;
                editor.runCommand("open-assets", {
                    onSelect: function (t) {
                        var newSrc = t.attributes.src;
                        conteudoImagemLink = $(editor.getSelected().toHTML());
                        var elConteudoImagem = $($(conteudoImagemLink[0]).children('a')).children('img');
                        $(elConteudoImagem)[0].src = newSrc;
                        editor.getSelected().set('content', conteudoImagemLink[0].innerHTML);
                        editor.DomComponents.render();
                        editor.select(null);
                        selecionado = null;
                        editor.Modal.close(), editor.AssetManager.setTarget(null);
                    }
                });
            },
            'mouseenter': function(){
                if(!selecionado){
                    editor.select(this.model);
                    var openSmBtn = editor.Panels.getButton('views', 'open-blocks');
                    openSmBtn.set('active', 1);
                }
            },
            'mouseleave': function(){
                if(!selecionado){
                    editor.select(null);
                    var openSmBtn = editor.Panels.getButton('views', 'open-blocks');
                    openSmBtn.set('active', 1);
                }else{
                    editor.select(selecionado)
                }
            }
        },
    })
});

And a Custom Command (I found where error is happening):

editor.Commands.add('opcoesBloco', {
    run: function(editor, sender){
        const bm = editor.BlockManager;
        const pn = editor.Panels;
        var selectedBlock = editor.getSelected();
        const id = 'views-container';
        const mkeditorCustom = document.createElement('div');
        const panels = pn.getPanel(id) || pn.addPanel({ id });
        if(selectedBlock){
            if(blocoSelecionado.attributes.type == "imagemLink"){
                const divTotal = document.createElement('div');
                divTotal.className = 'col-md-12';
                const divUm = document.createElement('div');
                divUm.className = 'col-md-4';
                const divDois = document.createElement('div');
                divDois.className = 'col-md-8';
                var elLink = $(blocoSelecionado.attributes.content);
                var elImagem = $(elLink).children('img');
                var nomeArquivo = elImagem[0].src.split('/').slice(-1)[0];
                const arquivo = document.createElement('span');
                arquivo.innerHTML = nomeArquivo;
                arquivo.style = 'display: block; color:#000000';
                const tamanho = document.createElement('span');
                tamanho.style = 'display: block; color: #000000; font-size: 11px';
                const imagem = document.createElement('img');
                imagem.src = elImagem[0].src;
                imagem.style = 'max-width: 100%';
                tamanho.innerHTML = imagem.naturalWidth + ' x ' + imagem.naturalHeight;
                const botao = document.createElement('a');
                botao.style = "margin-top:10px; color: #848080; cursor: pointer;text-decoration: underline; font-size: 15px;";
                botao.innerHTML = "Change Image";
                conteudoImagemLink = $(blocoSelecionado.toHTML());
                botao.onclick = function(){
                    editor.runCommand("open-assets", {
                        onSelect: function (t) {
                            var newSrc = t.attributes.src;
                            $($(divUm).children('img')[0])[0].src = newSrc;
                            var nomeNovaImagem = newSrc.split('/').slice(-1)[0];
                            $(divDois).children('span')[0].innerHTML = nomeNovaImagem;
                            var elConteudoImagem = $($(conteudoImagemLink[0]).children('a')).children('img');
                            $(elConteudoImagem)[0].src = newSrc;
******************************** ERROR HERE ********************************
                            blocoSelecionado.set('content', conteudoImagemLink[0].innerHTML);
                            editor.DomComponents.render();
                            editor.Modal.close(), editor.AssetManager.setTarget(null)
                        }
                    });
                };
                mkeditorCustom.style = "margin-top: 30px; text-align: left; padding-left: 20px";
                divUm.appendChild(imagem);
                divDois.appendChild(arquivo);
                divDois.appendChild(tamanho);
                divDois.appendChild(botao);
                mkeditorCustom.appendChild(divUm);
                mkeditorCustom.appendChild(divDois);
                panels.set('appendContent', mkeditorCustom).trigger('change:appendContent');
                this.mkeditorCustom = mkeditorCustom;
            }else{
                mkeditorCustom.append(editor.TraitManager.getTraitsViewer().el);
                panels.set('appendContent', mkeditorCustom).trigger('change:appendContent');
                this.mkeditorCustom = mkeditorCustom;
            }
        }
        this.mkeditorCustom.style.display = 'block';
    },
    stop: function(editor, sender){
        if(tinymce.editors.length > 0) tinymce.remove("#ckeditor");
        const mkeditorCustom = this.mkeditorCustom;
        mkeditorCustom && (mkeditorCustom.style.display = 'none');

    }
});

When I set the new link for child img, any block I add to editor, is adding twice, and when I select this duplicated block, both are selected and changed: image

Answers (3)

artfSeptember 17, 20181 reactions

@JulyanoF you should never do this editor.DomComponents.render() if you feel like you need that function, probably you're doing something wrong... then in your custom component, you don't set isComponent method, so please review this guide: https://grapesjs.com/docs/modules/Components.html for the rest, provide a live demo with the issue

artfSeptember 20, 20181 reactions

I'm trying getting html of selected element (editor.getSelected().toHTML()), manipulating it and changing original content

This is wrong... You should use Component's API, don't touch the view or even worse, its HTML. If you don't understand this concept (you should EDIT the MODEL of the component, not its VIEW) you will face a lot of issues

JulyanoFSeptember 17, 20180 reactions

@artf you are right. the problem is using render() function, that is duplicating the elements.. but, if I remove this function, the editor html didn't change.. it still showing old content and not the new. How can I avoid it? I will provide a live demo

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...

Browse Plugin Categories

Jump directly to plugin category pages on the marketplace.