Issue #429Opened October 17, 2017by sonnylloyd0 reactions

custom component save

Question

hi @artf sorry to be a pain i really didn't want to open a issue ticket but i have been stuck for days trying to achieve my end goal

i have made a simple plugin that adds icon support (font awsom) so i have a components.js a block.js and a main.js with some configs

i have managed to get the onchange working, however i dont know how to update the modal as on refresh the new selected icon goes back to the default icon. im sure i am doing something wrong and i have looked through all your gjs and cant figure it out

block.js

bm.add('icon', {
    label: 'Icon',
    attributes: {
      title: 'Insert Icon',
      class: 'fa fa-asterisk',
    },
    content: `<span data-gjs-custom-name="icon" data-gjs-draggable="*" data-gjs-droppable="false" class="icon"></span>`,
  });

component.js

domc.addType('icon', {
    model: defaultModel.extend({
      defaults: Object.assign({}, defaultModel.prototype.defaults, {
        iconslist: c.icons,
        icon: c.icon,
        draggable: '.col',
        droppable: false,
        traits: [
          {
            type: 'select',
            label: 'Icon',
            name: 'iconslist',
            changeProp: 1,
            options: c.icons
          }],
        script: function() {}
      }),
      init() {
        var icon = this.get('icon');
        console.log('init', icon);
        this.listenTo(this, 'change:iconslist', this.updateIcons);
      },
      updateIcons() {
        var icon = this.get('iconslist');
        this.set('icon',icon);
        const view = this.view;
        if (view) {
          var i = view.el.querySelector('[data-js=icon]');
          i.className = "";
          i.classList.add('fa');
          i.classList.add(icon);
        }
      },
    }, {
      isComponent: function(el) {
        if (hasClass(el, 'icon')) {
          return {
            type: 'icon'
          };
        }
      },
    }),
    view: defaultView.extend({
      init() {
        const comps = this.model.get('components');
        if (!comps.length) {
          comps.reset();
          comps.add(`
              <i data-js="icon" class="fa ${c.icon}"></i>
          `);
        }
      }
    }),
  });

and in the main.js i have some defaults set up (i have cut this down)

let defaults = {
icon: 'fa-snapchat-ghost',
icons: [
{
        "value": "fa-glass",
        "name": "glass"
      },
      {
        "value": "fa-music",
        "name": "music"
      }
]
}

Answers (3)

artfOctober 17, 20170 reactions

Hi @sonnylloyd I think the problem is that you're not reflecting correctly the icon property. Try with this

...model
// Try to leave inside the model only "model-related" stuff,
updateIcons() {
        this.set('icon', this.get('iconslist'));
},

...view
init() {
    this.listenTo(this.model, 'change:icon', this.updateIcon);
}
updateIcon() {
     const icon = this.model.get('icon');
     this.el.innerHTML = `<i data-js="icon" class="fa ${icon}"></i>`;
}
render() {
     defaultView.prototype.render.apply(this);
     this.updateIcon();
     return this;
}
sonnylloydOctober 17, 20170 reactions

Thanks @artf i have been playing with your suggestion but with no luck. again sorry for being a pain

heres the updated component.js

  domc.addType('icon', {
    model: defaultModel.extend({
      defaults: Object.assign({}, defaultModel.prototype.defaults, {
        icon: c.icon,
        icons: c.icons,
        tagName: 'icon',
        draggable: '.col',
        droppable: false,
        traits: [
          {
            type: 'select',
            label: 'icons',
            name: 'icons',
            options: c.icons
          }]
      }),
      init() {
        console.log('init 1');
        this.listenTo(this, 'change:icons', this.updateIcons);
      },
      updateIcons() {
          console.log('im here 1');
          this.set('icon', this.get('icons'));
      }
    }, {
      isComponent: function(el) {
        if (hasClass(el, 'icon')) {
          return {
            type: 'icon'
          };
        }
      },
    }),
    view: defaultView.extend({
      init() {
        console.log('im here 2');
        this.listenTo(this.model, 'change:icon', this.updateIcon);
        const comps = this.model.get('components');
        if (!comps.length) {
          comps.reset();
          comps.add(`
              <i data-js="icon" class="fa ${c.icon}"></i>
          `);
        }
      },
      updateIcon() {
         const icon = this.model.get('icon');
         console.log('updateIcon',icon);
         this.el.innerHTML = `<i data-js="icon" class="fa ${icon}"></i>`;
      },
      render() {
           defaultView.prototype.render.apply(this);
           this.updateIcon();
           return this;
      }
    }),
  });
artfOctober 18, 20170 reactions

@sonnylloyd check better my code, you've changed init() inside the model which was ok in your previous code. As you see, under the ...model, you only have to change the updateIcons()

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.