Issue #1895💬 AnsweredOpened March 15, 2019by simplecommerce0 reactions

Drag component over canvas with script, script appended multiple times.

快速解答by simplecommerce

So I dug around and figured that it was the updateScript method in the canvasView that was being called every time a script property is found on a component, regardless if its still being dragged or not over the canvas. I did some patching to test and it seemed to have fixed the issue. I had to overwrite it this way a...

Read full answer below ↓

Question

Hi, not sure if this is a bug or not.

But I noticed a weird behavior, when I drag a block that has a component that contains a script function, it seems to append it into the canvas before its being dropped.

And as you drop it, it appends another time, the script.

If you never drop the block and just drag over and out over and out, it appends as many times as possible.

And it never seems to clearn when I click clear canvas, I had to manually do:

editor.Canvas.getCanvasView().getJsContainer().innerHTML = '';

To clear the canvas JS.

Here is a screen shot of the issue on your demo page.

image

Answers (3)

simplecommerceMarch 17, 2019

So I dug around and figured that it was the updateScript method in the canvasView that was being called every time a script property is found on a component, regardless if its still being dragged or not over the canvas.

I did some patching to test and it seemed to have fixed the issue.

I had to overwrite it this way as I did not want to modify the original code directly, in case it gets fixed in the future.

Didn't know how to detect if the model was currently being dragged, only noticed that when the component is dropped in the canvas, updateScript is called, modelOpt had an extra attribute at, so relied on this.

Until someone makes a better, cleaner fix.

    const canvasView = editor.Canvas.getCanvasView();
    canvasView.updateScript = function(view) {
      // check if at attribute exists, if not assume we are still dragging
      if (!isUndefined(view.modelOpt.at)) {
        const model = view.model;
        const id = model.getId();        

        // check if we have previously inserted the script, if so, remove it
        let previousScript = this.getJsContainer().querySelector(`script[data-model-id="${id}"]`);
        if (previousScript !== null) previousScript.parentElement.remove();
        
        if (!view.scriptContainer) {
          view.scriptContainer = document.createElement('div');
          this.getJsContainer().appendChild(view.scriptContainer);
        }

        view.el.id = id;
        view.scriptContainer.innerHTML = '';
        // In editor, I make use of setTimeout as during the append process of elements
        // those will not be available immediately, therefore 'item' variable
        const script = document.createElement('script');
 
        // set custom attribute for script tag, in order to detect it, to remove it when dragging the same block within the canvas
        script.setAttribute('data-model-id', id);

        script.innerHTML = `
            setTimeout(function() {
              var item = document.getElementById('${id}');
              if (!item) return;
              (function(){
                ${model.getScriptString()};
              }.bind(item))()
            }, 1);`;
        // #873
        // Adding setTimeout will make js components work on init of the editor
        setTimeout(() => view.scriptContainer.appendChild(script), 0);
      }
    }
simplecommerceMarch 31, 2019

My previous solution did not work, so I had to scrap it, so I re-opened the issue.

artfApril 3, 2019

Hi @simplecommerce if you think it's a bug, please open an issue by FOLLOWING the template and create a reproducible live demo of the issue. It's really important because as we don't have a lot of free time we risk to waste a big part of it on debugging issue not related to the library itself

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 →

Browse Plugin Categories

Jump directly to plugin category pages on the marketplace.