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.37k stars 4.05k forks source link

Text fields in BlockManager and nested components #100

Closed noone-silent closed 7 years ago

noone-silent commented 7 years ago

I'm currently working on a bootstrap plugin for grapesjs and came across some problems.

Here is a part of my boostrap plugin to reproduce the failures:


blockManager.getAll().reset();

// Bootstrap Component
var comps = editor.DomComponents;
var defaultType = comps.getType('default');
var defaultModel = defaultType.model;
var defaultView = defaultType.view;

comps.addType('bootstrap', {
    model: defaultModel.extend({
        randomHex: function () {
            return Math.floor(Math.random() * 16777216).toString(16);
        },
        init: function () {
            if (typeof this.config.name !== "undefined") {
                this.name = this.config.name;
            } else {
                this.name = 'Box';
            }
        }
    }),
    view: defaultView.extend({
        deepAdd: function (model) {
            var className = this.model.randomHex();
            model.get('classes').add({name: className, label: className, active: true, type: "class"});
            var sm = model.sm.get("SelectorManager");
            sm.add(className);

            // var comps = model.get('components');
            // for (var i in comps.models) {
            //     this.deepAdd(comps.models[i]);
            // }
        },
        render: function () {
            this.deepAdd(this.model);
            defaultView.prototype.render.apply(this, arguments);
            return this;
        }
    })
});
blockManager.add('panel-default', {
    label: 'Default panel',
    content: {
        type: "bootstrap",
        classes: ["panel", "panel-default"],
        components:[{
            tagName: "div", type: "bootstrap", removable: true, draggable: false, copyable: false, classes: ["panel-heading"], components: [
                {tagName: "h3", type: "text", classes: ["panel-title"], removable: false, content: "Your title goes here"}
            ]
        }, {
            tagName: "div", type: "bootstrap", draggable: false, classes: ["panel-body"], components: [
                {typeName: "span", type: "text", content: "Your content goes here"}
            ]
        }]
    },
    attributes: {class: 'fa fa-square-o'}
});

One of the main problems is the following: If I edit the text in h3.panel-title or the span in .panel-body, the text gets removed after I leave the element. If I mark some of the text and make it bold or italic and leave the element, only the transformed text remains.

If I then reload the page and edit the transformed text, the text gets removed after I leave the element. No matter what i do. Sometimes it happens directly if I double click into the element

artf commented 7 years ago

Hi @noone-silentrunner I didn't test your code but one of the problems might be the absence of 'isComponent' method, I've also mentioned this in wiki:

  // The second argument of .extend are static methods and we'll put inside our
  // isComponent() method. As you're putting a new Component type on top of the stack,
  // not declaring isComponent() might probably break stuff, especially if you extend
  // the default one.
  {
    isComponent: function(el) {
      if(el.tagName == 'INPUT'){
        return {type: 'input'};
      }
    },
  }

Anyway, I don't even think you need to create a new component, maybe a simple block is enough:

blockManager.add('panel-default', {
    label: 'Default panel',
    attributes: {class: 'fa fa-square-o'}
    content: `
     <div class="panel panel-default">
       <div class="panel-heading" data-gjs-draggable="false" data-gjs-copyable="false">
         <h3 class="panel-title">Your title goes here</h3>
       </div>
       <div class="panel-body">Your content goes here</div>
     </div>`,
});
noone-silent commented 7 years ago

Hi, the missing isComponent method was the problem. After adding this, everything works like expected. Thank you.

The component is needed to add an additional class to every element to style them separately and don't overwrite any bootstrap default classes, or is there any other method for this?

artf commented 7 years ago

ah ok in that case custom component is necessary

lock[bot] commented 5 years ago

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.