How to dynamically modify a dropdown in a previously created JSON block

1,846 views
Skip to first unread message

Simon Bailey

unread,
Jul 26, 2017, 11:19:09 AM7/26/17
to Blockly
I have a block that is created using JSON and I want to modify the contents of its drop-down menu at runtime using javascript.

I can get the block and I can get the menu, but when I modify the contents of the menu nothing seem to happen and the block remains the same.

This is the code I am using:

    var gotoBlock = Blockly.Block.obtain(primaryWorkspace, 'block_goto');
   
var options = [["option1", "option1"], ["option2", "option2"]];
   
var drop = gotoBlock.getField("LABEL");
    drop
.menuGenerator_ = options;


Why is my block not changing?

Also I have also seen this article here https://developers.google.com/blockly/custom-blocks/dropdown-menus#dynamic_menu which looks like it would do what I want but it only shows how it can be done when the block is created in javascript. Is there a way of doing this using JSON?


Andrew n marshall

unread,
Jul 27, 2017, 1:27:40 AM7/27/17
to blo...@googlegroups.com
Hi Simon,

When using JSON, the preferred route for dynamic elements is through an extension, or quite possibly a full mutator (read/write generated option save state). The extension function is call when a new block of the given type is instantiated, given you the opportunity to add a new FieldDropDown with the menu item generator function, just like those in the Dynamic Menu section.

Blockly.Extensions.registerExtension('my_dynamic_dropdown_extension',
  new function() {
    var dynamicOptions = function() { ... }
    var dropdown = new Blockly.FieldDropdown(dynamicOptions);
    this.inputList[0].appendField(dropdown, 'MY_DYNAMIC_DROPDOWN')
  });


Andrew

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Message has been deleted

Simon Bailey

unread,
Jul 28, 2017, 12:09:58 PM7/28/17
to Blockly
Hi Andrew,

I think I am getting somewhere but I have an error that I'm not sure how to resolve.

Here is the JSON I am now using to create the block:

{
 
"type": "block_goto",
 
"message0": "Goto %1","args0" :
 
[
   
{
     
"type": "field_dropdown",
     
"name": "LABEL",
     
"options":
     
[
       
["Label1","Label1"],
       
["Label2","Label2"]
     
]
   
}
 
],
 
"previousStatement": null,
 
"nextStatement": null,
 
"colour": 60,
 
"tooltip": "",
 
"helpUrl": "",
 
"extensions": ["test_extension"]
}

and here is the javascript where I am attempting to add the extension:

    Blockly.Extensions.registerExtension('test_extension',

   
new function() {
       
var dynamicOptions = function () {

           
var options = [["option1", "option1"], ["option2", "option2"]];

           
return options;

       
}
       
var dropdown = new Blockly.FieldDropdown(dynamicOptions);

       
this.inputList[0].appendField(dropdown, 'LABEL')
   
});

However it is throwing the error 'Unable to get property '0' of undefined or null reference.' on the last line. It appears that this.inputList is NULL. I am new to javascript as well as Blockly so I dont quite understand what is going on or what exactly 'this' refers to in this instance.


Erik Pasternak

unread,
Jul 28, 2017, 3:49:44 PM7/28/17
to Blockly
Hi Simon,

It sounds like the 'this' is getting confused somewhere. It may be because of the 'new' keyword in front of your extension function. If removing new doesn't help take a look at how we define some of the math block extensions.

Another issue you'll run into, you're adding the field but it has the same name as the field you declared in JSON. This will leave you with two fields named LABEL and will break some of the code for looking up fields by name.

Cheers,
Erik
Message has been deleted

Erik Pasternak

unread,
Aug 25, 2017, 4:28:53 PM8/25/17
to Blockly
Hi Frédéric,

Using an extension to add the dropdown field and its dynamic dropdown should work (instead of adding it in the JSON). We have an open issue to expose a setter for the dynamic dropdown so it can be set on an already created dropdown, but haven't implemented it yet.

Cheers,
Erik

On Tue, Aug 22, 2017 at 11:44 PM, Frédéric
HI,

I am also very interested in the solution to that request.
How should we do if we would like to avoid the double creation of field LABEL ?
Is there a kind of `updateField` instead of `appendField` ?

--
You received this message because you are subscribed to a topic in the Google Groups "Blockly" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/blockly/4yDynlV-Q1I/unsubscribe.
To unsubscribe from this group and all its topics, send an email to blockly+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Erik Pasternak | Master of the House | epas...@google.com     
Reply all
Reply to author
Forward
0 new messages