Issue #2379Opened November 5, 2019by gentritabazi2 reactions

Update Content Before Load

Question

I have build one CMS in Laravel and i used GrapesJS to make Page Builder its perfect, i just created one component for "Posts" so users can select category where wants to select posts also limit. After select or change limit or category a request is made to a request to backend to show me data in JSON and i append to GrapesJS. I save all page content to database via command of GrapesJS: editor.store().html

Now how i can make to load fresh posts from Database from that category (Pic 1 & 2) that selected in builder. Because GrapesJS show me only html code.

Component Picture 1

Component Picture 2

Code to load Page Content for Page

$page = Pages::find($id);
$pageContent = $page->content; // here is content from GrapesJS
return view('page')->with('pageContent', $pageContent);

Component Code:

function posts(editor) {
    // Trait -> Limit Post per page
    editor.TraitManager.addType('limitPostPerPage', {
        createInput({ trait }) {
            const traitOpts = trait.get('options') || [];
            const options = traitOpts.lenght ? traitOpts : [
                { id: '', name: 'Select Category...' },
                { id: '8', name: 'Sport' },
                { id: '9', name: 'Global news' },
            ];
        
            const el = document.createElement('div');
            el.className = "postsSettings";
            el.innerHTML = `
                <div class="group">
                    <label>Category:</label>
                    <select type="select" class="inputCategory">
                    ${options.map(opt => `<option value="${opt.id}">${opt.name}</option>`).join('')}
                    </select>
                </div>
                <div class="group">
                    <label>Limit post per Page</label>
                    <input type="number" class="inputLimitPostPerPage"/>
                </div>
            `;
        
            const inputLimitPostPerPage = el.querySelector('.inputLimitPostPerPage');
            const inputCategory = el.querySelector('.inputCategory');
            inputCategory.addEventListener('change', ev => {
                // console.log('inputCategory: ' + ev.target.value);
            });
            inputLimitPostPerPage.addEventListener('change', ev => {
                // console.log('LimitPostPerPage: ' + ev.target.value);
            });
    
            return el;
        },
        onEvent({ elInput, component, event }) {
            var category = elInput.querySelector('select').value;
            var limitPostPerPage = elInput.querySelector('input').value;

            $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': laravel_csrf_token } });
            $.ajax({
                type: 'POST',
                url: getPostsListUrl,
                data: { category: category, limitPostPerPage: limitPostPerPage },
                success: function(data) {
                    if(data.status == 'success') {
                        component.set('content', data.html);
                    }
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    $.growl.error({ message: XMLHttpRequest.responseText });
                },
                fail: function(XMLHttpRequest, textStatus, errorThrown) {
                    $.growl.error({ message: XMLHttpRequest.responseText });
                },
            });
        },
    });

    // Component -> Posts
    editor.DomComponents.addType('postsComponent', {
        model: {
            defaults: {
                testprop: 1,
                traits: [
                    {
                        type: 'limitPostPerPage',
                        name: 'limitPostPerPage',
                        label: 'Posts Settings',
                        options: [
                            { value: 'link', name: 'Link' },
                            { value: 'popup', name: 'Popup' },
                        ],
                    },
                ],
            },
        },
        view: {
        },
    });

    // Block -> Posts
    var html = '<div class="container">'+
'                    <div class="row pt-4" data-gjs-type="postsComponent">'+
'                        <div class="col-lg-4 col-sm-6 mb-4" cool_disabled_v2="true" data-gjs-editable="false" data-gjs-removable="false">'+
'                            <div class="card h-100">'+
'                                <a href="#">'+

'                                </a>'+
'                                <div class="card-body">'+
'                                    <h4 class="card-title">'+
'                                        <a href="#" data-gjs-editable="false" data-gjs-removable="false" data-gjs-stylable="false">Post 1</a>'+
'                                    </h4>'+
'                                    <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet numquam aspernatur eum quasi sapiente nesciunt? Voluptatibus sit, repellat sequi itaque deserunt, dolores in, nesciunt, illum tempora ex quae? Nihil, dolorem!</p>'+
'                                </div>'+
'                            </div>'+
'                        </div>'+
'                        <div class="col-lg-4 col-sm-6 mb-4" cool_disabled_v2="true" data-gjs-editable="false" data-gjs-removable="false">'+
'                            <div class="card h-100">'+
'                                <a href="#">'+

'                                </a>'+
'                                <div class="card-body">'+
'                                    <h4 class="card-title">'+
'                                        <a href="#">Post 2</a>'+
'                                    </h4>'+
'                                    <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet numquam aspernatur eum quasi sapiente nesciunt? Voluptatibus sit, repellat sequi itaque deserunt, dolores in, nesciunt, illum tempora ex quae? Nihil, dolorem!</p>'+
'                                </div>'+
'                            </div>'+
'                        </div>'+
'                        <div class="col-lg-4 col-sm-6 mb-4" cool_disabled_v2="true" data-gjs-editable="false" data-gjs-removable="false">'+
'                            <div class="card h-100">'+
'                                <a href="#">'+

'                                </a>'+
'                                <div class="card-body">'+
'                                    <h4 class="card-title">'+
'                                        <a href="#">Post 3</a>'+
'                                    </h4>'+
'                                    <p class="card-text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet numquam aspernatur eum quasi sapiente nesciunt? Voluptatibus sit, repellat sequi itaque deserunt, dolores in, nesciunt, illum tempora ex quae? Nihil, dolorem!</p>'+
'                                </div>'+
'                            </div>'+
'                        </div>'+
'                    </div>'+
'                </div>';
    editor.BlockManager.add('posts', {
        label: 'Posts',
        category: 'Basic',
        attributes: { class: 'fa fa-clipboard' },
        content: html,
        draggable: true,
        editable: false,
    });
}

Answers (2)

artfNovember 7, 20192 reactions

@gentritabazi01

here

if(data.status == 'success') {
	component.set('content', data.html);
}

you can use component.components(data.html) this will replace the content with a new one returned from the server

pouyamiralayiNovember 6, 20190 reactions

@gentritabazi01 as far as i know, relying on editor storage for your custom data layer logic is not a good idea.

I save all page content to database via command of GrapesJS: editor.store().html

you can use:

editor.load(['gjs-components'], components => {
   // your parsing logic
})

above code can be inside init hook of either your model or your view definition. that way you have a list of objects that is easier to parse. cheers!

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.