GrapesJS / grapesjs

Free and Open source Web Builder Framework. Next generation tool for building templates without coding
https://grapesjs.com
Other
22.65k stars 4.1k forks source link

Need a feature to integrate modal form #2317

Closed suchiitsme closed 5 years ago

suchiitsme commented 5 years ago

[FEATURE REQUESTS] I have to add block which should a open a modal with form fields. Based on the form data selected I have to generate a html string and insert it to editor. and on click /double click of the component, modal should open again with the form details. How can I do this? Please help.

jcarizza commented 5 years ago

Hello @suchiitsme i think you can implement a component type.

comps.addType('custom-form', {
      model: defaultModel.extend({
        defaults: {
          ...defaultModel.prototype.defaults,
          removable: false,
          draggable: false,
          copyable: false,
          editable: true,
          propagate: ["removable", "draggable", "copyable", "editable"]}
      }, {
        isComponent: function(el){
          result = "";
          if (el.tagName === "form" && el.getAttribute("class").toString().indexOf("customForm") > -1) {
            result = {type: "custom-form"}
          }
          return result
        }
      }),
      view: defaultView.extend({
        defaults: {...defaultView.prototype.defaults},
        events: {
          click: function(event) {
              alert("Do anything")
            }
          }
        }
      }),
    });
suchiitsme commented 5 years ago

Hello @suchiitsme i think you can implement a component type.

comps.addType('custom-form', {
      model: defaultModel.extend({
        defaults: {
          ...defaultModel.prototype.defaults,
          removable: false,
          draggable: false,
          copyable: false,
          editable: true,
          propagate: ["removable", "draggable", "copyable", "editable"]}
      }, {
        isComponent: function(el){
          result = "";
          if (el.tagName === "form" && el.getAttribute("class").toString().indexOf("customForm") > -1) {
            result = {type: "custom-form"}
          }
          return result
        }
      }),
      view: defaultView.extend({
        defaults: {...defaultView.prototype.defaults},
        events: {
          click: function(event) {
              alert("Do anything")
            }
          }
        }
      }),
    });

Thank you. I will give a try!!

suchiitsme commented 5 years ago

Hi How do I link this to block?

artf commented 5 years ago

@suchiitsme As illustrated here you can create activatable (eg. you can trigger them on the drop from blocks or with a double click event) components in this way:

editor.DomComponents.addType('your-custom-component', {
    view: {
        events: {
            dblclick: 'onActive',
        },

        onActive(ev) {
            ev && ev.stopPropagation();
            // Eg. you can store you're form data in the component model
            const formData = this.model.get('form-data') || [];

            // Eg. open modal and render inside your "form builder"
            // elements based on formData
            yourOpenModalFn(formData, (newFormData) => {
                // Eg. callback function when someone confirmes new data
                this.model.set('form-data', newFormData);
            })
        }
    }
});

Now you can use the component in blocks

editor.BlockManager.add('your-custom-block', {
      label: 'Your label',
      content: { type: 'your-custom-component' }, // Component ID type
      activate: true, // This will trigger onActive method when the block is dropped
});