Issue #452Opened October 26, 2017by thecodefish0 reactions

Custom Resizer issue (or maybe how I'm saving/loading components)

Question

I'm trying to build a custom resizer for one of my components. It's a grid/column layout based on Flexbox and I want users to be able to resize one column (to a fixed width) and have the other columns fill up the remaining space.

I already have a custom component for my column, so I added resizer configuration to it, including an updateTarget() function, and it works great. However, if I save that content, and then come back to it, the updateTarget() function never gets invoked. New components that I add to the canvas work fine, but existing ones do not.

Here's my config:

{
    type: 'grid-col',
    'custom-name': 'Column',
    classes: ['flex-item'],
    resizable: {
        tl: 0, tc: 0, tr: 0,
        bl: 0, bc: 0, br: 0,
        updateTarget: function(element, rect, context)
        {
            //console.log('custom updateTarget invoked');

            var elStyle = element.style;

            elStyle.width = rect.w + 'px';
            elStyle.minWidth = rect.w + 'px';
            elStyle.maxWidth = rect.w + 'px';
            elStyle.flexGrow = 0;
        }
    }
}

When I save the content, this is what I end up with:

{
    //snip
    "resizable": {
        "tl": 0,
        "tc": 0,
        "tr": 0,
        "bl": 0,
        "bc": 0,
        "br": 0
    }
    //snip
}

Note that there is no reference to an updateTarget() function.

My assumption is when the editor loads existing content (I'm using editor.setComponents()) it loads straight from the component JSON and ignores whatever might be present in the Component Manager - is this correct? That could explain why my custom function is never called. Instead it falls back to the built in updateTarget() which updates the width property only.

I'm unsure if this is a problem with the custom resizer, a problem with how setComponents() works, or something I'm doing wrong.

Either way I'd appreciate some help in figuring out how to get my resizer function called properly for both new and existing components.

Cheers

Answers (3)

artfOctober 27, 20170 reactions

Yeah, you're right. This happens just because functions are not serializable, therefore when grapesjs calls JSON.stringify(Component) are simply ripped off. The solution for your case is to override toJSON method in the custom Component

editor.DomComponents.addType('grid-col', {
     model: ..
            defaults: ... // here you define your resizable
             ...
            // and then avoid its storing
            toJSON() {
               const obj = defaultModel.prototype.toJSON.apply(this, arguments);
               delete obj.resizable;
               return obj;
            }
          ...
     view:...
});
    
thecodefishOctober 30, 20170 reactions

Thanks @artf that did the trick.

sakshigarg9February 26, 20190 reactions

@thecodefish How do you change initial state of the Resizer properties? Where does this config go if I'm using the grapesjs-preset-webpage, simply under grapesjs.init{...}? I want to fix a minimum dimension for an image component specifically and disable a few of the corner points like tl, tc, tr.

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.