Toolbox

The toolbox is the side menu from whence the user may create new blocks. The structure of the toolbox is specified with XML, which may be either a tree of nodes, or a string representation. This XML is passed to Blockly when it is injected into the page. If you don't like typing XML manually, we recommend that you check out Blockly Developer Tools. With it, you can construct a toolbox and automatically generate its toolbox XML using a visual interface.

Here is a minimal example, using a tree of nodes:

<xml id="toolbox" style="display: none">
  <block type="controls_if"></block>
  <block type="controls_whileUntil"></block>
</xml>
<script>
  var workspace = Blockly.inject('blocklyDiv',
      {toolbox: document.getElementById('toolbox')});
</script>

Here is the same example, using a string representation:

<script>
  var toolbox = '<xml>';
  toolbox += '  <block type="controls_if"></block>';
  toolbox += '  <block type="controls_whileUntil"></block>';
  toolbox += '</xml>';
  var workspace = Blockly.inject('blocklyDiv', {toolbox: toolbox});
</script>

Both of the above create the same toolbox with two blocks:

If there are a small number of blocks, then they may be displayed without any categories (as in the minimal example above). In this simple mode all the available blocks are shown in the toolbox, there are no scrollbars on the main workspace, and the trashcan is not needed.

Categories

The blocks in the toolbox may be organized in categories. Here are two categories ('Control' and 'Logic'), each of which contain three blocks:

<xml id="toolbox" style="display: none">
  <category name="Control">
    <block type="controls_if"></block>
    <block type="controls_whileUntil"></block>
    <block type="controls_for">
  </category>
  <category name="Logic">
    <block type="logic_compare"></block>
    <block type="logic_operation"></block>
    <block type="logic_boolean"></block>
  </category>
</xml>

Below is the resulting toolbox, with the 'Logic' category clicked so that the three logic blocks in the flyout may be seen:

The presence of categories changes Blockly's UI to support larger applications. Scrollbars appear, allowing for an infinitely large workspace. A trashcan appears. Context menus contain more advanced options such as adding comments or collapsing blocks. All of these features may be overriden using the configuration options.

There are two categories that have special behaviours. Variable and function categories are defined with no contents, but with a 'custom' property of 'VARIABLE' or 'PROCEDURE' respectively. These categories will be populated automatically with the appropriate blocks.

<category name="Variables" custom="VARIABLE"></category>
<category name="Functions" custom="PROCEDURE"></category>

Note: The word 'procedure' is used throughout the Blockly codebase, but the word 'function' has since been found to be more understandable by students. Sorry for the mismatch.

Each category can be assigned a colour using the optional colour attribute. Note the British spelling. The colour is a number (0-360) defining the hue.

<xml id="toolbox" style="display: none">
  <category name="Logic" colour="210">...</category>
  <category name="Loops" colour="120">...</category>
  <category name="Math" colour="230">...</category>
  <category name="Colour" colour="20">...</category>
  <category name="Variables" colour="330" custom="VARIABLE"></category>
  <category name="Functions" colour="290" custom="PROCEDURE"></category>
</xml>

This colour appears as a rectangle to the left of the category, and as highlighting for the currently selected category:

Tree of Categories

Categories may be nested within other categories. Here are two top-level categories ('Core' and 'Custom'), each of which contain two sub-categories, each of which contain blocks:

<xml id="toolbox" style="display: none">
  <category name="Core">
    <category name="Control">
      <block type="controls_if"></block>
      <block type="controls_whileUntil"></block>
    </category>
    <category name="Logic">
      <block type="logic_compare"></block>
      <block type="logic_operation"></block>
      <block type="logic_boolean"></block>
    </category>
  </category>
  <category name="Custom">
    <block type="start"></block>
    <category name="Move">
      <block type="move_forward"></block>
      <block type="move_backward"></block>
    </category>
    <category name="Turn">
      <block type="turn_left"></block>
      <block type="turn_right"></block>
    </category>
  </category>
</xml>

Note that it is possible for a category to contain both sub-categories and blocks. In the above example, 'Custom' has two sub-categories ('Move' and 'Turn'), as well as a block of its own ('start').

Categories are shown collapsed by default when Blockly is loaded, but a category may be expanded with <category name="..." expanded="true">.

Block Groups

The XML may contain customized blocks, or groups of blocks. Here are four blocks:

  1. A simple logic_boolean block:
  2. A math_number block that has been modified to display the number 42 instead of the default of 0:
  3. A controls_for block that has three math_number blocks connected to it:
  4. A math_arithmetic block that has two math_number shadow blocks connected to it:

Here is the code to generate these four blocks in a toolbox:

<xml id="toolbox" style="display: none">
  <block type="logic_boolean"></block>

  <block type="math_number">
    <field name="NUM">42</field>
  </block>

  <block type="controls_for">
    <value name="FROM">
      <block type="math_number">
        <field name="NUM">1</field>
      </block>
    </value>
    <value name="TO">
      <block type="math_number">
        <field name="NUM">10</field>
      </block>
    </value>
    <value name="BY">
      <block type="math_number">
        <field name="NUM">1</field>
      </block>
    </value>
  </block>

  <block type="math_arithmetic">
    <field name="OP">ADD</field>
    <value name="A">
      <shadow type="math_number">
        <field name="NUM">1</field>
      </shadow>
    </value>
    <value name="B">
      <shadow type="math_number">
        <field name="NUM">1</field>
      </shadow>
    </value>
  </block>
</xml>

The XML for these customized blocks or groups is the same as Blockly's XML save format. Thus, the easiest way to construct the XML for such blocks is to use the Code application to build the blocks, then switch to the XML tab and copy the result. The x, y, and id properties are ignored by the toolbox and may be stripped out.

Shadow blocks are placeholder blocks that perform several functions:

  • They indicate the default values for their parent block.
  • They allow users to type values directly without needing to fetch a number or string block.
  • Unlike a regular block, they get replaced if the user drops a block on top of them.
  • They inform the user of the type of value expected.

Shadow blocks cannot be constructed with the Code application directly. Instead one can use regular blocks, then change <block ...> and </block> in the XML to <shadow ...> and </shadow>.

Separators

Adding a <sep></sep> tag between any two categories will create a separator.

By default every block is separated from its lower neighbour by 24 pixels. This separation may be changed using the 'gap' attribute, which will replace the default gap.

<xml id="toolbox" style="display: none">
  <block type="math_number"></block>
  <sep gap="32"></sep>
  <block type="math_arithmetic">
    <field name="OP">ADD</field>
  </block>
  <sep gap="8"></sep>
  <block type="math_arithmetic">
    <field name="OP">MINUS</field>
  </block>
</xml>

Adjusting the gaps between blocks allows one to create logical groups of blocks in the toolbox.

Buttons and Labels

You can put a button or label anywhere you can put a block in the toolbox.

<xml id="toolbox" style="display: none">
  <block type="logic_operation"></block>
  <label text="A label" web-class="myLabelStyle"></label>
  <label text="Another label"></label>
  <block type="logic_negate"></block>
  <button text="A button" callbackKey="myFirstButtonPressed"></button>
  <block type="logic_boolean"></block>
</xml>

<style>
.myLabelStyle>.blocklyFlyoutLabelText {
  font-style: italic;
  fill: green;
}
</style>

You may specify a CSS class name to apply to your button or label. In the above example, the first label uses a custom style, while the second label uses the default style.

Buttons should have callback functions; labels should not. To set the callback for a given button click, use

yourWorkspace.registerButtonCallback(yourCallbackKey, yourFunction).

Your function should accept as an argument the button that was clicked. The "Create variable..." button in the variable category is a good example of a button with a callback.

Disabled

Blocks in a toolbox may be inividually disabled using the optional disabled attribute:

<xml id="toolbox" style="display: none">
  <block type="math_number"></block>
  <block type="math_arithmetic"></block>
  <block type="math_single" disabled="true"></block>
</xml>

Disabling blocks may be used to restrict the user's choices. Perhaps advanced blocks might be unlocked after certain achievements.

Changing the Toolbox

The application may change the blocks available in the toolbox at any time with a single function call:

workspace.updateToolbox(newTree);

As was the case during initial configuration, newTree may either be a tree of nodes, or a string representation. The only restriction is that the mode cannot be changed; that is if there were categories in the initially-defined toolbox then the new toolbox must also have categories (though the categories may change). Likewise, if the initially-defined toolbox did not have any categories, then the new toolbox may not have any categories.

Be aware that at this time updating the toolbar causes some minor UI resets:

  • In a toolbox with categories, the flyout will close if it was open.
  • In a toolbox without categories, any fields changed by the user (such as a dropdown) will revert to the default.
  • Any toolbox so long that it extends beyond the page will have its scrollbar jump to the top.

Here is a live demo of a tree with categories and block groups.