[QUESTION] Drag component over canvas with script, script appended multiple times.
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.

Answers (3)
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);
}
}
My previous solution did not work, so I had to scrap it, so I re-opened the issue.
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.
Issue #1815
[Bug]: component:mount is fired multiple times
I had been using editor events and I noticed that component:mount event fires multiple times when a component is dragged from blocks to can...
Issue #1727
[QUESTION] Event to get children view
I have a problem with a component. When I drop a component into the canvas I create a simple object. Before appending this object I need to...
Issue #1186
[Bug] Number trait returns 'undefined'
Hello, it's either a bug or a question, i don't know yet. I defined a new component with - beside others - a number trait, as you can see o...
Issue #1308
I am not able to insert icon and its class in html element
bm.add('test-block', { label: "Icons", category: "Prismanote Blocks", content: { script: function () { var d = window.parent.window.modalJ;...
Paid Plugins That Match This Issue
Curated by issue keywords and label relevance to help you ship faster.
Loading paid plugin recommendations...
Browse Plugin Categories
Jump directly to plugin category pages on the marketplace.