Disable the start block in toolbox if start block is dragged to the workspace

797 views
Skip to first unread message

Vivek

unread,
Apr 10, 2019, 7:45:37 AM4/10/19
to Blockly
Hi all,

I am using start block in scratch junior and I want that If I dragged the start block in workspace then it should be shown as disable block in the toolbox.
I have used this code(as given below) in block definition and block is getting disabled but in toolbox it still shows start block as normal and untill I click on another category.

this.setDisabled_(true);
setDisabled_: function(workspace){
       var workspace = this.workspace;
   
         if( Blockly.Javascript.start_block_created  ==true)
         {
           this.setDisabled(true);
         }
       
   },


I want to show the start block as disabled immediately once the user drag start block into the workspace.

Thank You
Vivek

Beka Westberg

unread,
Apr 10, 2019, 10:11:31 AM4/10/19
to Blockly
Hi Vivek,

If you only want to run blocks connected to the start block, and you only want to have a single start block, I think another solution would be to create a single non-deletable start block, such as referenced here. This way you could completely remove the start block from the toolbox and not have to worry about disabling / enabling it.

var workspace = Blockly.inject('blocklyDiv', options);
var xml =
 
'<xml>' +
   
'<block type="start_block" deletable="false" movable="false"></block>' +
 
'</xml>';
Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(xml), workspace);
(All of the above should work in scratch blocks.)

If you also want information on how to do the enabling/disabling stuff I can probably write something up. I'm thinking it'll probably have to do with using dynamic toolbox categories.

I hope that helps!
Beka

Vivek

unread,
Apr 11, 2019, 12:44:24 AM4/11/19
to Blockly
Hi Beka,

Thanks for your solution and its working, but I want to implement enabling/disabling stuff in scratch junior blocks. Because I have some other blocks also which need to be used only once in the workspace.
If enabling/disabling stuff works then it will solve my bunch of tasks.
If you can help in this then it will be great and it will resolve my many problems I am facing in scratch.

Thank You
Vivek

Beka Westberg

unread,
Apr 11, 2019, 10:34:25 AM4/11/19
to Blockly
Hi Vivek,

So setting a limit on the number of blocks of a type is... tricky. I implimented this feature a while ago for blockly, but it doesn't look like scratch blocks has taken this change in yet. You can create a dynamic category to disable things in the toolbox, but that won't handle things like copy pasting. Here's an example of a dynamic 'LOGIC' category that checks if the controls_if has been created:

function logicFlyoutCallback(workspace) {
 
// If you're only checking top blocks you can also use
 
// workspace.getTopBlocks()
 
var allBlocks = workspace.getAllBlocks();
 
var xmlList = [];
 
 
var ifCreated;
 
// Check if one of the blocks on the workspace is the 'controls_if' block.
 
for (var i = 0, block; block = allBlocks[i]; i++) {
   
switch (block.type) {
     
case 'controls_if':
        ifCreated
= true;
       
break;
     
// More block checks here
   
}
 
}


 
// If it has not been added to the workspace, add it to the
 
// toolbox, otherwise add it to the toolbox, but disabled.
 
if (!ifCreated) {
    xmlList
.push(Blockly.Xml.textToDom(
     
'<xml><block type="controls_if"></block></xml>'
   
).firstChild);
 
}
 
else {
    xmlList
.push(Blockly.Xml.textToDom(
     
'<xml><block type="controls_if" disabled="true"></block></xml>'
   
).firstChild);
 
}


 
/* Add Other Blocks */
  xmlList
.push(Blockly.Xml.textToDom(
   
'<xml><block type="logic_compare"></block></xml>'
 
).firstChild);
  xmlList
.push(Blockly.Xml.textToDom(
   
'<xml><block type="logic_operation"></block></xml>'
 
).firstChild);
  xmlList
.push(Blockly.Xml.textToDom(
   
'<xml><block type="logic_negate"></block></xml>'
 
).firstChild);
  xmlList
.push(Blockly.Xml.textToDom(
   
'<xml><block type="logic_boolean"></block></xml>'
 
).firstChild);
  xmlList
.push(Blockly.Xml.textToDom(
   
'<xml><block type="logic_ternary"></block></xml>'
 
).firstChild);


 
// Return the category structure.
 
return xmlList;
}

For more information on dynamic toolbox categories (including how to actually hook a function like this into blockly) see this page.

For a more complete way of setting the Max Instances for a block type check out this PR.

I hope that helps! If you have any further questions please reply!
Beka

Vivek

unread,
Apr 22, 2019, 9:15:29 AM4/22/19
to Blockly
Hi Beka,
Hope you are doing fine.
Please tell me where should I write this code.
Is this need to be written in html file where the xml for the toolbox is written or into the core folder.

Thank You
Vivek

Beka Westberg

unread,
Apr 22, 2019, 10:01:04 AM4/22/19
to Blockly
Hi Vivek,

It shouldn't matter where you write it as long as you register it in the following way:

myWorkspace.registerToolboxCategoryCallback('MY_CUSTOM_CALLBACK', customCallbackFunction);

Where myWorkspace is your workspace, MY_CUSTOM_CALLBACK is the string you put in the 'custom' category XML attribute, and customCallbackFunction is your customCallbackFunction (i.e. it might need to be myApplication.customCallbackFunction depending on where you write it).

If you want to keep it simple there shouldn't be any problem with writing it in your HTML file (within script tags) and then registering it right after you inject your workspace.

I hope that helps! For more info about dynamic categories see this.
Beka
Reply all
Reply to author
Forward
0 new messages