Specify data-ids for menu blocks?

66 views
Skip to first unread message

KTBYTE Computer Science Academy

unread,
Sep 13, 2022, 11:32:29 AM9/13/22
to Blockly
Hi,

I'm maintaining a collaborative Blockly editor and am trying to add a feature that allows the mouse cursor position of one user's editor to sync across to other users. I don't need the cursor's position to be exactly correct, but it should be accurate enough to see which element the user is hovering on (a block in the main workspace, a category in the toolbox, or a block in the toolbox flyout menu). I have to account for potentially different screen sizes and zoom levels across different users, so I'm making a solution that involves grabbing the hovered element's id (when hovering over <div>'s like the categories in the toolbox) or data-id (when hovering over blocks).

The toolbox category ids can be specified in the XML/JSON with the "toolboxitemid" attribute. However blocks have randomly generated data-ids. That's not a problem with blocks in the main workspace because the MouseCreate events object (which I sync across different users' editors) include the generated id. However, I'm having trouble identifying which block is hovered in the toolbox flyout menu. I have a hacky way that works right now, but is somewhat brittle. 

Is there a way to specify custom data-ids for blocks in the toolbox XML/JSON definition?

thanks!


Aaron Dodson

unread,
Sep 13, 2022, 2:29:36 PM9/13/22
to Blockly
Hi,

Are you able to get a reference to the block objects in the toolbox at all, or is that why you're trying to customize the data-id value? If you just need a stable identifier for blocks in the toolbox across instances, I wonder if the .data property on Block might be helpful? It doesn't change the data attribute value, but if you can get a reference to the block object you could set/get your own identifier there.

- Aaron

KTBYTE Computer Science Academy

unread,
Sep 13, 2022, 4:20:04 PM9/13/22
to Blockly
Hm... I just tried the data property thing but it doesn't seem to show up as attribute in the block's SVG element. When user A is hovering over the SVG element for block X in their flyout menu, I want a reference to the corresponding SVG element for block X in user B's flyout menu. I can get a reference to the SVG <g> element user A is hovering over by doing something like this:

     document.addEventListener('mousemove', (e) => {
          const elementForUserA = e.target..closest('.blocklyDraggable');
     });

But I can't use that element to easily figure out the corresponding SVG <g> element in user B's flyout menu, as they have different data-id's. (Right now I do it by using document.querySelectorAll() to get an array of all blocks in the flyout menu for user A, see which index i corresponds to the elementForUserA, then message userB to get a reference to the i-th block in userB's flyout menu. It works ok but I was hoping for a cleaner solution)

Is there a way to get the Block JS object based on which <g> element userA is hovering over? Or vice versa (given a Block object, get the corresponding <g> element ?)


Aaron Dodson

unread,
Sep 13, 2022, 4:39:45 PM9/13/22
to Blockly
Hi,

Thanks for clarifying! You can indeed get the block JS object from the <g> element - calling Blockly.getMainWorkspace().getFlyout().getWorkspace().getBlockById(gElement.getAttribute('data-id')) should do the trick. From that block object, you can get the corresponding <g> element by calling getSvgRoot(). Hopefully that helps some - let me know if you run into any trouble or have further questions!

- Aaron
Reply all
Reply to author
Forward
0 new messages