Issue #2043Opened May 28, 2019by megarg0 reactions

[QUESTIONS] Adding custom component does not work

Question

I have done a lot of research but still could not add a custom component. I tried the example in official docs (to modify behavior of "input" element and it is working fine). https://grapesjs.com/docs/modules/Components.html#define-new-component

But the above example is for modifying existing component ("input").

I am trying to figure out how to create a new component. Following is my code, but it is not working (I am not printing anything in console when I drag it in the form). - note that I used the official example and changed it a bit to create this custom component.

Please help on what I may be doing wrong here...

  comps.addType('input2', {
      // Define the Model
      model: defaultModel.extend({
        // Extend default properties
        defaults: Object.assign({}, defaultModel.prototype.defaults, {
          // Can be dropped only inside `form` elements
          draggable: 'form, form *',
          // Can't drop other elements inside it
          droppable: false,
Code SnippetTEXT
// Traits (Settings)
            
            }),
          },
          // 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 == 'INPUT2'){
                console.log('I am at isComponent: el:', el);
                return {type: 'input2'};
              }
            },
          }),

          // Define the View
          view: defaultType.view.extend({
          // Bind events
          events: {
            // If you want to bind the event to children elements
            // 'click .someChildrenClass': 'methodName',
            click: 'handleClick',
            dblclick: function(){
              alert('Hi!');
            }
          },

          // It doesn't make too much sense this method inside the component
          // but it's ok as an example
          randomHex: function() {
            return '#' + Math.floor(Math.random()*16777216).toString(16);
          },

          handleClick: function(e) {
            this.model.set('style', {color: this.randomHex()}); // <- Affects the final HTML code
            this.el.style.backgroundColor = this.randomHex(); // <- Doesn't affect the final HTML code
            // Tip: updating the model will reflect the changes to the view, so, in this case,
            // if you put the model change after the DOM one this will override the backgroundColor
            // change made before
          },

          // The render() should return 'this'
          render: function () {
            // Extend the original render method
            defaultType.view.prototype.render.apply(this, arguments);
            this.el.placeholder = 'My Text here'; // <- Doesn't affect the final HTML code
            return this;
          },
        }),
      });


       // A block for the custom component
       editor.BlockManager.add('input2', {
          label: 'My custom component',
          attributes: {
            class:'input2'
          },
          content: {
            // Built-in 'map' component
            type: 'input2',
            tagName: 'INPUT2',
           // style: { height: '350px'},
            // Once inserted it can't be removed (just an example)
            removable: false
          }
        
        //content: (<div>Foo</div>),
      });

Answers (1)

artfMay 30, 20190 reactions

First of all, use the improved API. The isComponent is triggered only if you need to parse an HTML string, if you pass the component object (eg. { type: 'input2', }) the parsing is not necessary.

You don't see anything in the canvas because obviously there is no INPUT2 element in HTML5

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.