[英]Blockly: Update other inputDummy dropdown fields based on selection of a inputDummy dropdown field
I've been trying to make a custom block in the Blockly workspace that changes the options in drop-down fields based on the selection of a previous drop-down field in the same block.我一直在尝试在 Blockly 工作区中创建一个自定义块,该块根据对同一块中前一个下拉字段的选择来更改下拉字段中的选项。 About the block:-
关于区块:-
I've implemented an 'onchange' function to the blockly initialization that gets the change data through the 'event' variable and responds accordingly.我已经实现了一个'onchange' function 到通过'event'变量获取更改数据并相应响应的块初始化。 I'm having problems trying to update the changing drop-down fields.
我在尝试更新不断变化的下拉字段时遇到问题。 Please assist.
请协助。
Code代码
// the block JSON declaration variable
var updateTableData = {
"type": "al_update_table_data",
"message0": "Update in table %1 where column %2 is %3 set value for column %4 to %5",
"args0": [
{
"type": "input_dummy",
"name": "table_input",
},
{
"type": "input_dummy",
"name": "column_input",
},
{
"type": "input_value",
"name": "get_value"
},
{
"type": "input_dummy",
"name": "column_input1",
},
{
"type": "input_value",
"name": "set_value"
}
],
"inputsInline": false,
"previousStatement": null,
"nextStatement": null,
"fieldRow": false,
"colour": 90,
"tooltip": "Update value in a table",
"helpUrl": "",
"extensions": ["get_tables", "get_column", "get_column1"],
}
// the blockly extensions
// get list of tables and populate the 'table_input' drop-down field
Blockly.Extensions.register('get_tables', function () {
this.getInput("table_input")
.appendField(new Blockly.FieldDropdown(
function () {
let options = []
let tables = JSON.parse(localStorage.getItem('applab_myTables'))
tables.map(t => options.push([t.name, t.id]))
return options
}
), "table_input")
})
// get list of columns from the first table and populate the 'column_input' drop-down field
Blockly.Extensions.register('get_column', function () {
this.getInput('column_input')
.appendField(new Blockly.FieldDropdown(
function () {
let options = []
let table = JSON.parse(localStorage.getItem('applab_myTables'))[0]
Object.keys(table['columnData']).filter(cId => table['columnOrder'].includes(cId)).map(cId => options.push([table['columnData'][cId]['name'], cId]))
return options
}
), 'column_input')
})
// get list of columns from the first table, remove the column value already selected in 'column_input' and populate the 'column_input1' drop-down field
Blockly.Extensions.register('get_column1', function () {
var selectedColumn = this.getFieldValue('column_input')
this.getInput('column_input1')
.appendField(new Blockly.FieldDropdown(
function () {
let options = []
let table = JSON.parse(localStorage.getItem('applab_myTables'))[0]
Object.keys(table['columnData']).filter(cId => table['columnOrder'].includes(cId)).filter(cId => cId !== selectedColumn).map(cId => options.push([table['columnData'][cId]['name'], cId]))
return options
}
), 'column_input1')
})
// Comments with 7 slashes (///////) are my commentary on the issues, errors and outputs that I get
// blockly block initialization
Blockly.Blocks['al_update_table_data'] = {
init: function () {
this.jsonInit(updateTableData)
},
onchange: function (event) {
// console.log(event.type)
var table_id = this.getFieldValue('table_input')
var selectedcolumn = this.getFieldValue('column_input')
var otherColumn = this.getFieldValue('column_input1')
if (event.blockId === this.id) {
if (event.type === Blockly.Events.BLOCK_CHANGE) {
// console.log('name of changed field', event.name)
// console.log('old value', event.oldValue)
// console.log('new value', event.newValue)
if (event.name === 'table_input') {
// change in selected table, update column_input and column_input1
} else if (event.name === 'column_input') {
// change in selected column, update column_input1
/////// I tried to removeField which did remove the field, but also the label on the same field row. But when I tried to getInput, I get the error: 'column_input1' input doesn't exist
// this.removeField('column_input1', true)
/////// I tried to removeInput as well, which too removed the field, but also the label on the same field row. And when I tried to getInput, I again get the error: 'column_input1' input doesn't exist
// this.removeInput('column_input1')
/////// This functions runs fine when I don't remove any input or field. But it keeps adding new drop-downs next to existing ones with new options
this.getInput('column_input1')
/////// I tried this to use removeField after getInput as well. But it shows the error: this.getInput().removeField() is not a function
// .removeField('column_input1')
.appendField(new Blockly.FieldDropdown(
function () {
let options = []
let table = JSON.parse(localStorage.getItem('applab_myTables')).find(table => table.id === table_id)
Object.keys(table['columnData']).filter(cId => table['columnOrder'].includes(cId)).filter(cId => cId !== event.newValue).map(cId => options.push([table['columnData'][cId]['name'], cId]))
return options
}
), 'column_input1')
}
}
}
if (event.type === Blockly.Events.FINISHED_LOADING) {
// workspace finished loading, update column_input and column_input1 based on selected table
}
}
}
Here is a snapshot of the block that is generated:这是生成的块的快照:
tldr; tldr; Update options of a drop-down field in a block when the selected option of another drop-down is changed.
当另一个下拉列表的选定选项更改时,更新块中下拉字段的选项。
Thanks, Utkarsh谢谢, 乌特卡什
Thanks to @beka from Google Blockly groups at https://groups.google.com/g/blockly .感谢来自https://groups.google.com/g/blockly的 Google Blockly 组的@beka。
The main problem here was conceptual.这里的主要问题是概念上的。 A block has
一个块有
Both the input and the field can have names.输入和字段都可以有名称。 And it is good practice to name them differently.
以不同的方式命名它们是一种很好的做法。
As seen in my extensions, I'd taken my input this.getInput('columnInput')
and appended a field .appendField
with the same name.正如在我的扩展中看到的那样,我接受了我的输入
this.getInput('columnInput')
并附加了一个具有相同名称的字段.appendField
。 Due to this, the input had a field with the same name.因此,输入具有相同名称的字段。
Here are the corrections:以下是更正:
Blockly.Extensions.register('get_column', function () { this.getInput('column_input') .appendField(new Blockly.FieldDropdown( function () { let options = [] let table = JSON.parse(localStorage.getItem('applab_myTables'))[0] Object.keys(table['columnData']).filter(cId => table['columnOrder'].includes(cId)).map(cId => options.push([table['columnData'][cId]['name'], cId])) return options } ), 'column_input_field') // updated the field name different from input name })
this.getInput('column_input').removeField('column_input_field') // first removed the field // and then, append a new field with the new options this.getInput('column_input') .appendField(new Blockly.FieldDropdown( function () { let options = [] let table = JSON.parse(localStorage.getItem('applab_myTables')).find(table => table.id === event.newValue) Object.keys(table['columnData']).filter(cId => table['columnOrder'].includes(cId)).map(cId => options.push([table['columnData'][cId]['name'], cId])) return options } ), 'column_input_field') // updated the field name different from input name
And ofcourse, if you personally face any issue while this.getInput('').removeField('')
, log the input object console.log(this.getInput(''))
and assess.当然,如果您在
this.getInput('').removeField('')
期间遇到任何问题,请记录输入 object console.log(this.getInput(''))
并评估。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.