Change default text in toolbox

248 views
Skip to first unread message

Bart Butenaers

unread,
Jul 14, 2018, 9:49:00 AM7/14/18
to Blockly
Hi,

I'm using the JSON object block library from Mark Friedman.

Currently one of his nodes shows "default" as default property name:


Is there any way to change that text value programmatically (before it is displayed in the toolbox), e.g. to "payload".
I don't want to change it in the original JS file from Mark, since I want to be able to upgrade it afterwards if Mark should ever publish a new version of his library.

Thanks !!
Bart

Andrew n marshall

unread,
Jul 14, 2018, 11:57:03 AM7/14/18
to blo...@googlegroups.com
The toolbox XML is mostly just serialized blocks, and you can override the value of a field using the <field>...</field> tags within the <block> tags.  Here is an example from our demos:

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



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

Bart Butenaers

unread,
Jul 14, 2018, 4:26:12 PM7/14/18
to Blockly
Hi Andrew,

That seems indeed to be the way to go.

However I have last week setup my Blockly web application like this:
  • The basic toolbox.xml file (from Google) is loaded from the server:
                var xml = null;
               
var request = new XMLHttpRequest();

                request
.open('GET', '/blocky/js/basic/toolbox.xml', false);  
                request
.send();
               
               
if (request.readyState == 4 && request.status == 200) {
                    xml
= request.responseXML;
               
}

  • In that loaded toolbox a new 'Json' category is created (for Mark's Json blocks) programmatically:
                var jsonCategory = document.createElement("category");
                jsonCategory
.setAttribute("name", "Json");
                jsonCategory
.setAttribute("colour", "#43b7ff");
                xml
.documentElement.insertBefore(jsonCategory, xml.documentElement.firstChild);

  • Mark's blocks are then added programmatically to the 'Json' category:
                [
                    CUSTOM_OBJECT_FROM_JSON_BLOCK_NAME
,
                    CUSTOM_OBJECT_TO_JSON_BLOCK_NAME
,
                    CUSTOM_OBJECT_GET_BLOCK_NAME
,
                    CUSTOM_OBJECT_SET_BLOCK_NAME
,
                    CUSTOM_OBJECT_CREATE_BLOCK_NAME
               
].forEach(function(blockType) {
                   
var jsonBlock = document.createElement("block");
                    jsonBlock
.setAttribute("type", blockType);
                    jsonCategory
.appendChild(jsonBlock);
               
}

  • At the end one large toolbox xml string is created (and loaded in the workspace):
                var toolbox = new XMLSerializer().serializeToString(xml.documentElement);

So if I want to use your proposal, I need to create a second toolbox.xml file for Mark's Json blocks.  In that file I could add the <field name="TEXT">payload</field> line...
But then I need to combine the toolbox.xml files (the one from Google and the one from Mark) into a single toolbox.
Do you have any suggestions how that could be accomplished??

Thanks again !!!
Bart

Andrew n marshall

unread,
Jul 14, 2018, 5:15:32 PM7/14/18
to blo...@googlegroups.com
The toolbox is actually loaded from the XML DOM. You can combine multiple partial toolboxes at the DOM level before passing them to Blockly in either the configuration options or via updateToolbox().

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

Bart Butenaers

unread,
Jul 15, 2018, 2:24:54 AM7/15/18
to Blockly
Andrew,

I now have created a separate toolbox.xml file for all the libraries (Google's basic blocks, Mark's Json blocks, and my own Node-Red blocks).
All 3 xml files are loaded into DOM, and combined into a single XML.
Below is my code, if anybody else would need it in the future:

                // Create a new XML document (which represents a toolbox)
               
var toolboxXml = document.implementation.createDocument(null, "toolbox");
               
               
[
                   
"/blocky/js/basic/toolbox.xml",
                   
"/blocky/js/json/toolbox.xml",
                   
"/blocky/js/nodered/toolbox.xml"
               
].forEach(function(filePath) {

                   
var request = new XMLHttpRequest();

                    request
.open('GET', filePath, false);  // `false` makes the request synchronous

                    request
.send();
               
                   
if (request.readyState == 4 && request.status == 200) {

                       
// Get all categories in the new XML document
                       
var newCategories = request.responseXML.getElementsByTagName("category");


                       
// Iterate backwards since categories can be moved away from this list (to the toolbox)
                       
for (i = newCategories.length - 1; i >= 0; --i) {
                           
var newCategory = newCategories[i];
                           
                           
// Get the category name
                           
var name = newCategory.getAttribute('name');

                           
// Try to find an existing category with the same name.
                           
// Indeed multiple toolboxes can put blocks in the same category...
                           
var existingCategory = toolboxXml.getElementsByName(name);
                           
                           
if (existingCategory.length === 0) {
                               
// If the new category didn't exist yet in the toolbox, move the entire new category to the start of the toolbox
                                toolboxXml
.documentElement.insertBefore(newCategory, toolboxXml.documentElement.firstChild);
                           
}
                           
else {
                               
var newBlocks = newCategory.children;
 
                               
// Move all the blocks (and their children) from the newCategory to the existingCategory
                               
for (var k = 0; k < newBlocks.length; k++) {
                                   
var newBlock = newBlocks[k];
                                    existingCategory
[0].appendChild(newBlock);
                               
}
                           
}
                       
}
                   
}
                   
else {
                        console
.log("Cannot load toolbox.xml for Blocky");
                   
}
               
});



Bart Butenaers

unread,
Jul 15, 2018, 3:03:12 AM7/15/18
to Blockly
Andrew,

this is emberassing, but don't get it to show "payload" instead of "default".
Tried a series of things, but don't get it managed ;-(

In the toolbox below you can see two experiments, one for object_get and one for object_set:

<xml xmlns="http://www.w3.org/1999/xhtml" id="toolbox" style="display: none;">
 
<category name="Json objects" colour="#43B7FF">
   
<block type="object_from_json"></block>
   
<block type="object_to_json"></block>
   
<block type="object_get">
       <value name="field_name">
       
<shadow type="field_input">
         
<field name="text">payload</field>
       
</shadow>      
     
</value>
 
   
</block>
   
<block type="object_set">
 
    <field name="text">payload</field>
   
</block>
   
<block type="object_create"></block>
 
</category>
</xml>

Bart

Andrew n marshall

unread,
Jul 15, 2018, 4:33:06 AM7/15/18
to blo...@googlegroups.com
In the JSON definition of your first message, the field name is "field_name", so <field name="field_name">payload</field> should go directly under <block to="object_get">. Your toolbox XML uses name="text".

I assume object_set is similar.


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

Bart Butenaers

unread,
Jul 15, 2018, 4:50:12 AM7/15/18
to Blockly
That did the job.  What a mistake to make ... 
Thanks a lot!!!
Reply all
Reply to author
Forward
0 new messages