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.38k stars 4.06k forks source link

Issue attaching event to new plugin in Anglar #2491

Closed sukheja-varun closed 4 years ago

sukheja-varun commented 4 years ago

Hi all, I was trying to add a new plugin to grapejs within my Angular project. Requirement: New plugin with name as Product. When the user drops the Product Plugin in HTML, it should open a modal where the user can type some attributes and an auto-complete search where the user can search multiple products and submit of modal I have to inject those products in HTML.

I checked the docs and found below example

  function myPlugin(editor){
      editor.BlockManager.add('my-first-block', {
        label: 'Simple block',
        content: '<div class="my-block">This is a simple block</div>',
      });
  }

But when I tried to work on this I was unable to :

pouyamiralayi commented 4 years ago

@sukheja-varun

attach any event to the new plugin

inside your plugin, you must first define a custom type component:

   editor.DomComponents.addType('my-first-type', {
            model: {
                defaults: {
                    components: '<div class="my-block">This is a simple block</div>',
                }
            }
    })

then define a new block which is using our previously defined custom component type:

    editor.BlockManager.add('my-first-block', {
            label: 'Simple block',
            content: {
                type: 'my-first-type'
            }
    });

for the modal, we define the below functions:

    const createContent = () => {
            const content = document.createElement('div');
            content.style = 'position: relative';
            content.innerHTML =
                `
                    <form onsubmit="">
                        <div >
                           <input  type="text" id="query" placeholder="search..." name="query" style="
                              margin-bottom:10px;
                              font-size: 1rem;
                              padding: 10px 20px;
                              border-radius: 3px;
                              border: none;
                           ">
                        </div>
                    </form>
                    <button style="
                        background-color: blue;
                        color:white;
                        font-size: 1rem;
                        border-radius: 5px;
                        border: none;
                        padding: 10px 20px;
                        cursor: pointer
                    ">
                        Submit
                    </botton>
                    `
            return content
    }

the createContent will generate the internal html for your modal.

        const applyChanges = () => {
            axios.post("http://example.com", {
                /*post body*/
            })
        }

the applyChanges is the click handler for the submit button inside the modal. and finally:

        const showModal = () => {
            const modal = editor.Modal
            const content = createContent()
            const btn = content.children.length === 2 && content.children[1];
            btn.addEventListener('click', applyChanges)
            modal.open({
                title: "My Dialog!",
                content: content
            })
        }

now that we have our component available as a block and we have a way to show our modal, we need to define a listener for the drop event inside our plugin:

    editor.on("canvas:drop", (dt, m) => {
            if (m && m.attributes && m.attributes.type == 'my-first-type') {
                /*our component is dropped, show the modal:*/
                showModal()
            }
    })

call API

as you can see inside applyChanges you can use whatever networking library you want, but there is no built-in networking library available inside grapesjs.

inject custom HTML

for injecting content inside your component, you can use either append or components. cheers!