How can I create two associated dropdown lists in one block

310 views
Skip to first unread message

Dubkov ilya

unread,
Nov 20, 2017, 8:24:31 AM11/20/17
to Blockly
Hi!

Is it possible to create two associated dropdown lists in one block, so when user select item in first list, second list is generated according to this item. 
For example I want to make a block that plays sounds. The sounds are divided into the banks. User  selects a bank from the first list, and then - boom - the second list is populated with sounds from that bank.

Thank you 

Andrew n marshall

unread,
Nov 20, 2017, 1:43:41 PM11/20/17
to blo...@googlegroups.com
It's possible, but tricky. You'll need two parts:
 * A mutator to store and restore the second drop down's value. Specifically the domToMutation and mutationToDom methods.
 * A change handler to update the contents of the second drop down.

The first is required because when the block reloads, the default loading code won't know about the available options to the second drop down.
The second is the code you're expecting, a change handler to adjust the contents of the second.

This is my rough attempt. It hasn't been tested, and so probably has more than a few bugs, but will get you a long way toward your goal.

// Block JSON:
{
  "name": "play_sound_bank",
  "message0": "Play sound %1",  // Second input added by mutator.
  "args0": [
    {
      "type": "field_dropdown",
      "name": "BANK",
      "options": [
        ["Bank #1", "BANK1"],
        ["Bank #2", "BANK2"],
        ["BANK #3", "BANK3"]
      ]
    }
  ],
  "inputsInline": true,
  "mutator":["second_drop_down"],
}

// Mutator definition:
Blockly.Extensions. registerMutator('second_drop_down', function() {
  domToMutation: function(xmlElement) {
    // Read <mutation sound_id="value id"/>
    this. soundId_ = xmlElement.getAttribute('sound_id'); // Second dropdown value.
    this.rebuildSecondDropDown_();
  }

  mutationToDom: function() {
    var mutationXml = document.createElement('mutation');
    mutationXml.setAttribute('sound_id', this.fieldValue('SOUND'));
    return mutationXml;
  }

  setOnChange: function(function(changeEvent) {
    this.rebuildSecondDropDown_();
  });

  // Helper function for adding/removing 2nd input and dropdown.
  rebuildSecondDropDown_: function() {
    if (this.getInput('INPUT2') {
      this.removeInput('INPUT2');
    }
    // (Re)Create dummy INPUT2 and second drop down 'SOUND' ...
    var menuOptions;
    switch(this.getFieldValue('BANK')) {
      case 'BANK1': /* Make menuOptions ... */ break;
      case 'BANK2': /* Make menuOptions ... */ break;
      case 'BANK3': /* Make menuOptions ... */ break;
    }
    var fdd2 = new FieldDropdown(menuOptions);
    fdd2.name = 'SOUND';
    fdd2.setValue(this.soundId_);
    this.appendDummyInput('INPUT2')
        .appendField(fdd);
  }
});


--
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.

Dubkov ilya

unread,
Nov 20, 2017, 9:03:38 PM11/20/17
to Blockly
Thank you, Andrew!
I'll definitely try your approach.

вторник, 21 ноября 2017 г., 1:43:41 UTC+7 пользователь Andrew n marshall написал:
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages