Issue #2793✓ SolvedOpened May 20, 2020by Lerdouille3 reactions

Extend Image Traits

快速解答by Lerdouille3

Hi again, here is the final solution to create a a href image : Now i have to found how to check the URL integrity when you want to update the href variable Best regards

Read full answer below ↓

Question

代码片段TEXT
Hello,

i would like to extend the image type with some options, specially with a redirect option on click.
I tried this solution after the editor initialization (i precise that i work in full javascript and non Node.js environment) : 
editor.DomComponents.addType('image', {
            isComponent: el => el.tagName == 'img',
            model: {
                defaults: {
                    traits: [
                      // Strings are automatically converted to text types
                        'alt', 
                        'title', // Same as: { type: 'text', name: 'name' }
                        { type: 'url', name: 'href', placeholder:'https://google.com', changeProp: 1 }
                      ],
                    // As by default, traits are binded to attributes, so to define
                    // their initial value we can use attributes
                    attributes: { type: 'title', required: false },
                },
                init() {
                    // Also the listener changes from `change:attributes:*` to `change:*`
                    this.on('change:url', this.handlePlhChange);
                },
                handlePlhChange() {
                    console.log('URL updated');
                },
            },
        });

So, with that code, i saw my URL input but i can't trigger the update.
My point is to intercept the input update and get the input value to use it to put my "img" DOM into a "a href" DOM

Any help would be great :)

Best regards

Answers (3)

👍 Most helpfulLerdouilleJune 26, 2020

Hi again,

here is the final solution to create a a href image :

editor.DomComponents.addType('imagelink', {
                model: {
                    defaults: {
                        tagName: 'div',
                        resizable: {keepAutoHeight: true},
                        droppable: false,
                        traits: [
                            { 
                                type: 'href', label: 'Source', name: 'href'
                            },
                            {
                                type: 'select',
                                label: 'Target',
                                name: 'target',
                                options: [
                                  { value: '', name: 'This window' },
                                  { value: '_blank', name: 'New window' }
                                ]
                            }
                        ],
                        components: [
                            {
                                resizable: false,
                                draggable: false,
                                droppable: false,
                                selectable: false,
                                hoverable: false,
                                type: 'link',
                                components: [{
                                    type: 'image',
                                    attributes: {
                                        src: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIHZpZXdCb3g9IjAgMCAyNCAyNCIgc3R5bGU9ImZpbGw6IHJnYmEoMCwwLDAsMC4xNSk7IHRyYW5zZm9ybTogc2NhbGUoMC43NSkiPgogICAgICAgIDxwYXRoIGQ9Ik04LjUgMTMuNWwyLjUgMyAzLjUtNC41IDQuNSA2SDVtMTYgMVY1YTIgMiAwIDAgMC0yLTJINWMtMS4xIDAtMiAuOS0yIDJ2MTRjMCAxLjEuOSAyIDIgMmgxNGMxLjEgMCAyLS45IDItMnoiPjwvcGF0aD4KICAgICAgPC9zdmc+',
                                        style:'width:100%;'
                                    },
                                    resizable: false,
                                    draggable: false,
                                    droppable: false,
                                    hoverable: false,
                                    selectable: false,
                                }]
                            }
                        ]
                    },
                    init() {
                      this.on('change:attributes:href', this.handleHrefChange);
                      this.on('change:attributes:target', this.handleTargetChange);
                    },
                    handleHrefChange: function ( component, value ) {
                        delete component.attributes.attributes;
                        component.attributes.components.models[0].attributes.attributes.href = value;
                        return false;
                    },
                    handleTargetChange: function ( component, value ) {
                        delete component.attributes.attributes;
                        component.attributes.components.models[0].attributes.attributes.target = value;
                        return false;
                    },
                },
            });

Now i have to found how to check the URL integrity when you want to update the href variable

Best regards

felipesoteroJune 5, 2020

I have the same need in my project. I tried creating a block, but I couldn't get the initial popup to "pop".

I tried creating a component with a plugin, but there's too much work that I can't understand how it can connect to each other.

Any hints or clues on what we both can do would be great!

Thanks!

artfJune 17, 2020

You've added this listener change:url but the name of the trait is name: 'href', so just change it with change:href

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...

Free option

Check the open-source GrapesJS plugins on GitHub or run a quick search in our free catalog.

Browse free plugins →
Premium option

Premium plugins ship with support, regular updates, and production-ready features — save days of integration work.

Browse premium plugins →

Related tutorials

In-depth guides on the same topic.

All tutorials →

Browse Plugin Categories

Jump directly to plugin category pages on the marketplace.