How to update the menu of a dropdown Field

165 views
Skip to first unread message

Jakob Krause

unread,
Jan 16, 2022, 5:44:35 PM1/16/22
to Blockly
Hello there,

I am currently working on a project where the menu of a dropdown field is an array which may be modified. Now if I rename one element I need to select the renamed option on all blocks.
My goal is that the menu gets updated in the same instance I update my array plus the dropdown field should select the option with the same index as before. Do you know how I can code this?

Many thanks in advance
Jakob Krause 

Jason Schanker

unread,
Jan 19, 2022, 1:12:38 AM1/19/22
to Blockly
Hi Jakob,

Do all the dropdowns share the same Array of options?  If so, the easiest way is to initialize a variable to your options Array and reference that Array in your block definition:

const workspace = Blockly.getMainWorkspace();
const optionsArr = [['Default option', 'DEFAULT'], ['Option B', 'OPTIONB'], ['Option C', 'OPTIONC']];
let currentOptionsArr = optionsArr.slice(); // used for comparison

Blockly.Blocks['sharedOptionsBlock'] = {
  init: function() {
    this.appendDummyInput().appendField(new Blockly.FieldDropdown(optionsArr), 'OPTS');
  }
};

If the renaming of an option only occurs on a workspace event, you could add a listener to the workspace to do a comparison of currentOptionsArr to optionsArr.  If there was a change, you can iterate over all the blocks of the specified type, selecting the appropriate new field value based on the differing index and then update the currentOptionsArr to be a (shallow) copy of optionsArr.

workspace.addChangeListener((e) => {
  const changedIndex = optionsArr.findIndex((option, index) => option[0] !== currentOptionsArr[index][0] || option[1] !== currentOptionsArr[index][1]);
  if (changedIndex !== -1) {
    Blockly.getMainWorkspace().getBlocksByType('sharedOptionsBlock').forEach(b => {
      b.setFieldValue(optionsArr[changedIndex][1], 'OPTS')
    });
    currentOptionsArr = optionsArr.slice();
  }
});

Best,
Jason

Beka Westberg

unread,
Jan 19, 2022, 8:03:04 AM1/19/22
to blo...@googlegroups.com
Hello Jakob,

You might also be able to use a variable field for this. They're called variable fields, but really they're just identifier fields. They automatically handle renamings and updating other relevant dropdowns. And if you're using variable fields elsewhere, you can always add a type filter, so that only the specific ones you want to show show up.

But if you don't want the names to be editable by users, then it probably won't work for your case.

Best of luck on your project!
--Beka

--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/blockly/832469df-f0ca-41ad-a5d7-922861cb8458n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages