Search code examples
jqueryblocklygoogle-blockly

Google Blockly UI on jQuery Dialog is not editable


While rendering Blockly UI in jQuery Dialog, it does not allow to edit the inputs.

Blockly UI IN Jquery Dialog

Reason is Blockly adding a div to DOM with an input field like below:

<div class="blocklyWidgetDiv" style="direction: ltr; display: block; left: 514.052px; top: 133.094px; width: 91.5547px;">
  <input class="blocklyHtmlInput" value="dfgfdgdfgdfg">
</div>

But the actual blocklyDiv is attached under jQuery Dialog. Input field directly attached to html body.

When I am moving the blocklyWidgetDiv inside Dialog, it showing input field some where in the page, not rendered in exact editor place.

enter image description here


Solution

  • I meanwhile found and solved the problem on my side.

    TL;DR: one of the containers of the Blockly workspace had a zoom factor different from 1 which was the reason for the wrong size and position of any input elements!

    Longer explanation

    Blockly overlays SVG display regions within its workspace by HTML form elements during input. While the workspace may be found anywhere deep in a document, the input element is placed in a direct child of the document body (and positioned absolutely depending on the SVG region's position). If any workspace parent has a zoom factor different from 1, the calculated position differs from the actual one and the input element is misplaced

    Possible solutions

    • get rid of that zoom factor (wasn't feasible for me as it was set by a library I am using)
    • let the Blockly developers place any form elements closer to the workspace (e.g., as a sibling of the outermost SVG element in a common container) - this would be the most robust solution (as "zoom" is not very well supported these days)
    • get "zoom" supported properly (this does not seem feasible)
    • write a hack that properly reshapes the input elements

    Unfortunately, I had to choose the last one.

    What I did:

    • let a MutationObserver look for those infamous form elements and
    • whenever a new form element appears, calculate the proper position and size of that element (that's a bit tricky)
    • then assign the proper size and the difference between original and proper position to the form element (as the container of that form element also plays a role in positioning and sizing)
    • additionally, resize the form element upon any user input
    • and listen to changes of the layout, e.g. due to window resizing...

    The result is a weird hack which is why I would like not to show the code to the public - in the long time, I would definitely recommend to place form elements closer to the Blockly workspace...

    Edit:

    unfortunately, this hack does not handle the problems which occur when trying to drag blocks into the trashcan with zoom factors much larger than 1.