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

[Question] How do I add elements/sectors to views container using a custom button in the Panel #2350

Closed AbdiasM closed 4 years ago

AbdiasM commented 4 years ago

I have added a custom button to the Panel as below:

    const pm = editor.Panels;        
    pm.addButton('views', {
        id: 'customButton',
        className: '',
        command: {
            run: function (editor) {
                alert("Hello");
            },
            stop: function (editor) {

            }
        },
        attributes: { class: 'fa fa-address-card-o' },
        active: false,
    });

I would like to add custom elements in the views-container when this button is clicked. Screen shot attached. Could you please help with this?

CustomButtonClick

ko06 commented 4 years ago

is this fixed?

AbdiasM commented 4 years ago

No, it isn't. Still trying to figure it out

pouyamiralayi commented 4 years ago

@AbdiasM @ko06 sorry for being late on this! based on #277

        const pn = editor.Panels
        let editPanel = null
        pn.addButton('views', {
            id: 'editMenu',
            attributes: {class: 'fa fa-address-card-o', title: "Edit Menu"},
            active: false,
            command: {
                run: function (editor) {
                    if(editPanel == null){
                        const editMenuDiv = document.createElement('div')
                        editMenuDiv.innerHTML = `
                        <div id="your-content">
                             Input: <input/>
                             <button>Button</button> 
                              <!-- eg. bind a click event on button and do something with GrapesJS API -->
                        </div>
                    `
                        const panels = pn.getPanel('views-container')
                        panels.set('appendContent', editMenuDiv).trigger('change:appendContent')
                        editPanel = editMenuDiv
                    }
                    editPanel.style.display = 'block'
                },
                stop: function (editor) {
                    if(editPanel != null){
                        editPanel.style.display = 'none'
                    }
                }

            }
        })

Cheers!

muhammadasifvaival commented 2 years ago

@AbdiasM @ko06 sorry for being late on this! based on #277

        const pn = editor.Panels
        let editPanel = null
        pn.addButton('views', {
            id: 'editMenu',
            attributes: {class: 'fa fa-address-card-o', title: "Edit Menu"},
            active: false,
            command: {
                run: function (editor) {
                    if(editPanel == null){
                        const editMenuDiv = document.createElement('div')
                        editMenuDiv.innerHTML = `
                        <div id="your-content">
                             Input: <input/>
                             <button>Button</button> 
                              <!-- eg. bind a click event on button and do something with GrapesJS API -->
                        </div>
                    `
                        const panels = pn.getPanel('views-container')
                        panels.set('appendContent', editMenuDiv).trigger('change:appendContent')
                        editPanel = editMenuDiv
                    }
                    editPanel.style.display = 'block'
                },
                stop: function (editor) {
                    if(editPanel != null){
                        editPanel.style.display = 'none'
                    }
                }

            }
        })

Cheers!

thanks it is very helpful for me

hc0127 commented 10 months ago

Hi, @pouyamiralayi . thanks for your post. I got custom view container. But I wanna use react components on that part. Is it possible? if so, Please help me.

Julhol-droid commented 9 months ago

Hi, @pouyamiralayi . thanks for your post. I got custom view container. But I wanna use react components on that part. Is it possible? if so, Please help me.

I think the right way to do this would be to use https://github.com/GrapesJS/react?tab=readme-ov-file

However I think that you would need to write the whole UI for the editor again. Which is not really nice

Julhol-droid commented 9 months ago

Hi, @pouyamiralayi . thanks for your post. I got custom view container. But I wanna use react components on that part. Is it possible? if so, Please help me.

I think the right way to do this would be to use https://github.com/GrapesJS/react?tab=readme-ov-file

However I think that you would need to write the whole UI for the editor again. Which is not really nice

It might also be possible to render a whole React Element like this Note taht you need to import ReactDom like this if you use React 18:

import ReactDOM from 'react-dom/client'

const editMenuDiv = document.createElement('div')
const root = ReactDOM.createRoot(editMenuDiv)  
root.render(<PagesComponent editor={editor} />)

inside PagesComponent.tsx

import { Editor } from 'grapesjs'
import React, { useCallback, useState } from 'react'

const PagesComponent = ({ editor }: { editor: Editor }) => {
  const [pages, setPages] = useState(editor.Pages.getAll())

  const handleAdd = useCallback(() => {
    editor.Pages.add({
      component: '<div class="my-class">My element</div>',
    })
    setPages(editor.Pages.getAll())
  }, [editor])

  return (
    <div>
      <button onClick={handleAdd}>Add Page</button>
      <div>
        {pages.map(page => (
          <div key={page.id}>{page.id}</div>
        ))}
      </div>
    </div>
  )
}