Preset field value and make it not editable

338 views
Skip to first unread message

Elena Ageeva

unread,
Jul 31, 2019, 3:07:36 AM7/31/19
to Blockly
Good Day, everyone.

I need an opportunity to preset my cycle conditions when I drag a block from Toolbox to Workspace, and not create a lot of the same block with this small difference.

So I have a block:

{
  type
: "cycleNumber",
  message0
: "%{BKY_CYCLE_1} %1 %{BKY_CYCLE_2} %2 %3",
  previousStatement
: null,
  nextStatement
: null,
  style
: "movement_blocks",
  tooltip
: "",
  helpUrl
: "",
  args0
: [
 
{
   type
: "field_number",
   name
: "cycleLength",
   min
: 0,
   max
: 5
 
},
 
{
   type
: "input_dummy"
 
},
 
{
   type
: "input_statement",
   name
: "NAME"
 
}
 
],
}

I use it like :

<block type="cycleNumber"><field name="cycleLength">3</field></block>

I decided to make my field not editable. I tried to set editable="false" in xml, tried to set it in arg0 in json, but it doesn't work, I still can type inside the field and change its value.

Any help will be very appreciate! 

Beka Westberg

unread,
Jul 31, 2019, 11:57:32 AM7/31/19
to Blockly
Hello,

Sadly there is no way to make a single field uneditable without making the whole block uneditable :/

You might be able to get away with using a serializable label field (I'm not certain about your circumstances). Just know that that's only available in recent versions of Blockly (I think it was added in 2.20190722.0, but it may have been 1.20190419.0).

If you want to add toggleable editablility to fields, it is possible but it will take a bit of work:

1. Add an editable_ property to the Blockly.Field class:
Blockly.Field.prototype.editable_ = true;

2. Add a setEditable function in the same file:
Blockly.Field.prototype.setEditable = function(editable) {
 
this.editable_ = editable;
};

3a. Update the isClickable function if you're using the latest release:
Blockly.Field.prototype.isClickable = function() {
 
return this.editable_ &&
     
!!this.sourceBlock_ && this.sourceBlock_.isEditable() &&
     
!!this.showEditor_ && (typeof this.showEditor_ === 'function');
};

3b. Or update the isCurrentlyEditable function if you're on an older release:
Blockly.Field.prototype.isCurrentlyEditable = function() {
 
return this.EDITABLE && this.editable_ &&
     
!!this.sourceBlock_ && this.sourceBlock_.isEditable();
};

4. Then you'll need to add a JSON extension to your block to set the field's editability.
Blockly.defineBlocksWithJsonArray([

 
{
    type
: "cycleNumber",
    message0
: "%{BKY_CYCLE_1} %1 %{BKY_CYCLE_2} %2 %3",
    previousStatement
: null,
    nextStatement
: null,
    style
: "movement_blocks",
    tooltip
: "",
    helpUrl
: "",
    args0
: [
     
{
        type
: "field_number",
        name
: "cycleLength",
        min
: 0,
        max
: 5
     
},
     
{
        type
: "input_dummy"
     
},
     
{
        type
: "input_statement",
        name
: "NAME"
     
}
   
],

   
"extensions": ["not_editable_extension"]
 
}
]);


Blockly.Extensions.register('not_editable_extension',
 
function() {
   
this.getField('cycleLength').setEditable(false);
 
});

5. If you're running in compressed mode (if you followed the fixed size workspace tutorial you're probably running in compressed mode) you'll need to rebuild blockly. Navigate to the root blockly directory through the command line and then run: python build.py core

If you'd like this to be added as a feature of Blockly you can put up a feature request here :D

I hope that helps! If you have any further questions please reply!
Beka
Message has been deleted

Elena Ageeva

unread,
Aug 1, 2019, 4:46:49 AM8/1/19
to Blockly
Hello, Beka!
Thank you so much for this manual, it really helped.

I injected first three steps in my app code, because I don't want to lose this changes after next blockly update. And now I have problems with Blockly.Extensions.register and webpack hot server. But I'll fill a new feature request for saving this code in main blockly, so don't worry.

Thank you one more time!

Erik Pasternak

unread,
Aug 1, 2019, 12:08:28 PM8/1/19
to Blockly
Just a note, if this field is never editable on this block and this is the only time you want a field that looks like a number but isn't editable you could:
  • create a new field that extends field_number.
  • override isClickable() to return false.
Alternatively, you could extend field_labelserializable and change the styling/background to make it look unique.
Reply all
Reply to author
Forward
0 new messages