Kolom dropdown menyimpan string sebagai nilainya dan string sebagai teksnya. Nilai adalah kunci netral bahasa yang akan digunakan untuk mengakses teks dan tidak akan diterjemahkan saat Blockly beralih antarbahasa. Teks adalah string yang dapat dibaca manusia yang akan ditampilkan kepada pengguna.
Kolom dropdown
Kolom dropdown dengan editor terbuka
Kolom dropdown pada blok yang diciutkan
Alat
Konstruktor dropdown mengambil generator menu dan validator opsional. Generator menu berupa array opsi (dengan setiap opsi berisi bagian yang dapat dibaca manusia dan string netral bahasa) atau fungsi yang menghasilkan array opsi. Bagian yang mudah dibaca dari setiap opsi dapat berupa string, gambar, atau elemen HTML dan array dapat berisi campuran opsi dari berbagai jenis.
Dropdown teks sederhana
JSON
{
"type": "example_dropdown",
"message0": "drop down: %1",
"args0": [
{
"type": "field_dropdown",
"name": "FIELDNAME",
"options": [
[ "first item", "ITEM1" ],
[ "second item", "ITEM2" ]
]
}
]
}
JavaScript
Blockly.Blocks['example_dropdown'] = {
init: function() {
this.appendDummyInput()
.appendField('drop down:')
.appendField(new Blockly.FieldDropdown([
['first item', 'ITEM1'],
['second item', 'ITEM2']
]), 'FIELDNAME');
}
};
Memisahkan informasi yang dapat dibaca manusia dari kunci netral bahasa
memungkinkan setelan menu dropdown dipertahankan di antara bahasa. Misalnya, versi Inggris dari suatu blok dapat menentukan [['left', 'LEFT'], ['right',
'RIGHT]]
, sedangkan versi Jerman dari blok yang sama akan menentukan [['links',
'LEFT'], ['rechts', 'RIGHT]]
.
Dropdown gambar
Opsi dalam menu dropdown dapat berupa gambar, yang direpresentasikan sebagai objek dengan properti src
, width
, height
, dan alt
.
JSON
{
"type": "image_dropdown",
"message0": "flag %1",
"args0": [
{
"type": "field_dropdown",
"name": "FLAG",
"options": [
["none", "NONE"],
[{"src": "canada.png", "width": 50, "height": 25, "alt": "Canada"}, "CANADA"],
[{"src": "usa.png", "width": 50, "height": 25, "alt": "USA"}, "USA"],
[{"src": "mexico.png", "width": 50, "height": 25, "alt": "Mexico"}, "MEXICO"]
]
}
]
}
JavaScript
Blockly.Blocks['image_dropdown'] = {
init: function() {
var input = this.appendDummyInput()
.appendField('flag');
var options = [
['none', 'NONE'],
[{'src': 'canada.png', 'width': 50, 'height': 25, 'alt': 'Canada'}, 'CANADA'],
[{'src': 'usa.png', 'width': 50, 'height': 25, 'alt': 'USA'}, 'USA'],
[{'src': 'mexico.png', 'width': 50, 'height': 25, 'alt': 'Mexico'}, 'MEXICO']
];
input.appendField(new Blockly.FieldDropdown(options), 'FLAG');
}
};
Dropdown HTML
Opsi dapat berupa elemen HTML apa pun, asalkan tidak terlalu besar dan tidak berupaya menangani peristiwa mouse atau keyboard. (Anda bertanggung jawab untuk mengikuti aturan ini -- Blockly tidak menerapkannya.)
Saat menu dropdown terbuka, daftar akan menampilkan elemen HTML. Saat ditutup
dan elemen adalah opsi yang dipilih, daftar akan menampilkan (dalam urutan preferensi
menurun) atribut title
elemen, atribut aria-label
, atau
properti innerText
.
JSON
{
"type": "flags_with_text_dropdown",
"message0": "flag with text %1",
"args0": [
{
"type": "field_dropdown",
"name": "FLAG_WITH_TEXT",
"options": [
["x", "X"], // Placeholder. An empty array throws an exception.
]
}
],
// Use an extension to add the HTML element options.
"extensions": ["flag_with_text_extension"]
}
Blockly.Extensions.register('flag_with_text_extension',
function() {
function createFlagWithTextDiv(text, src) {
const div = document.createElement('div');
div.setAttribute('style', 'width: 75px;');
div.setAttribute('title', text);
const img = document.createElement('img');
img.setAttribute('src', src);
img.setAttribute('style', 'height: 25px; display: block; margin: auto;');
div.appendChild(img);
const para = document.createElement('p');
para.innerText = text;
para.setAttribute('style', 'text-align: center; margin: 5px;');
div.appendChild(para);
return div;
}
const canadaDiv = createFlagWithTextDiv('Canada', 'canada.png');
const usaDiv = createFlagWithTextDiv('USA', 'usa.png');
const mexicoDiv = createFlagWithTextDiv('Mexico', 'mexico.png');
const options = [
['none', 'NONE'],
[canadaDiv, 'CANADA'],
[usaDiv, 'USA'],
[mexicoDiv, 'MEXICO']
];
this.getField('FLAG_WITH_TEXT').setOptions(options);
});
Hal ini dilakukan menggunakan ekstensi JSON.
JavaScript
function createFlagWithTextDiv(text, src) {
const div = document.createElement('div');
div.setAttribute('style', 'width: 75px;');
div.setAttribute('title', text);
const img = document.createElement('img');
img.setAttribute('src', src);
img.setAttribute('style', 'height: 25px; display: block; margin: auto;');
div.appendChild(img);
const para = document.createElement('p');
para.innerText = text;
para.setAttribute('style', 'text-align: center; margin: 5px;');
div.appendChild(para);
return div;
}
const canadaDiv = createFlagWithTextDiv('Canada', 'canada.png');
const usaDiv = createFlagWithTextDiv('USA', 'usa.png');
const mexicoDiv = createFlagWithTextDiv('Mexico', 'mexico.png');
Blockly.Blocks['flags_with_text_dropdown'] = {
init: function() {
const input = this.appendDummyInput()
.appendField('flag with text');
const options = [
['none', 'NONE'],
[canadaDiv, 'CANADA'],
[usaDiv, 'USA'],
[mexicoDiv, 'MEXICO']
];
input.appendField(new Blockly.FieldDropdown(options), 'FLAG_WITH_TEXT');
}
};
Dropdown dinamis
JSON
{
"type": "dynamic_dropdown",
"message0": "day %1",
"args0": [
{
"type": "field_dropdown",
"name": "DAY",
"options": [
["x", "X"], // Placeholder. An empty array throws an exception.
]
}
],
// Use an extension to set the menu function.
"extensions": ["dynamic_menu_extension"]
}
Blockly.Extensions.register('dynamic_menu_extension',
function() {
this.getField('DAY').setOptions(
function() {
var options = [];
var now = Date.now();
for(var i = 0; i < 7; i++) {
var dateString = String(new Date(now)).substring(0, 3);
options.push([dateString, dateString.toUpperCase()]);
now += 24 * 60 * 60 * 1000;
}
return options;
});
});
Hal ini dilakukan menggunakan ekstensi JSON.
JavaScript
Blockly.Blocks['dynamic_dropdown'] = {
init: function() {
var input = this.appendDummyInput()
.appendField('day')
.appendField(new Blockly.FieldDropdown(
this.generateOptions), 'DAY');
},
generateOptions: function() {
var options = [];
var now = Date.now();
for(var i = 0; i < 7; i++) {
var dateString = String(new Date(now)).substring(0, 3);
options.push([dateString, dateString.toUpperCase()]);
now += 24 * 60 * 60 * 1000;
}
return options;
}
};
Dropdown juga dapat disediakan dengan fungsi, bukan daftar opsi statis, yang memungkinkan opsi menjadi dinamis. Fungsi ini harus menampilkan
array opsi dalam format [human-readable-value, language-neutral-key]
yang sama dengan opsi statis. Setiap kali dropdown diklik, fungsi akan dijalankan dan opsi dihitung ulang.
Pemisah
Gunakan string 'separator'
untuk menambahkan garis di antara opsi dalam menu dropdown.
JSON
{
"type": "separator_dropdown",
"message0": "food %1",
"args0": [
{
"type": "field_dropdown",
"name": "FOOD",
"options": [
["water", "WATER"],
["juice", "JUICE"],
"separator",
["salad", "SALAD"],
["soup", "SOUP"],
]
}
]
}
JavaScript
Blockly.Blocks["separator_dropdown"] = {
init: function() {
var input = this.appendDummyInput()
.appendField("food1");
var options = [
["water", "WATER"],
["juice", "JUICE"],
"separator",
["salad", "SALAD"],
["soup", "SOUP"],
];
input.appendField(new Blockly.FieldDropdown(options), "FOOD");
}
};
Serialisasi
JSON
JSON untuk kolom dropdown terlihat seperti ini:
{
"fields": {
"FIELDNAME": "LANGUAGE-NEUTRAL-KEY"
}
}
Dengan FIELDNAME
adalah string yang mereferensikan kolom dropdown, dan
nilai adalah nilai yang akan diterapkan ke kolom. Nilai harus berupa
kunci opsi netral bahasa.
XML
XML untuk kolom dropdown terlihat seperti berikut:
<field name="FIELDNAME">LANGUAGE-NEUTRAL-KEY</field>
Jika atribut name
kolom berisi string yang mereferensikan kolom dropdown, dan teks dalamnya adalah nilai yang akan diterapkan ke kolom. Teks
dalam harus berupa kunci opsi netral bahasa yang valid.
Penyesuaian
Panah dropdown
Properti Blockly.FieldDropdown.ARROW_CHAR
dapat digunakan untuk mengubah
karakter Unicode yang merepresentasikan panah dropdown.
Properti ARROW_CHAR
secara default ditetapkan ke \u25BC
(▼) di Android dan \u25BE
(▾) di platform lainnya.
Ini adalah properti global, sehingga akan mengubah semua kolom dropdown saat disetel.
Tinggi menu
Properti Blockly.FieldDropdown.MAX_MENU_HEIGHT_VH
dapat digunakan untuk mengubah
tinggi maksimum menu. Tinggi ini ditentukan sebagai persentase tinggi area pandang, dengan area pandang adalah jendela.
Properti MAX_MENU_HEIGHT_VH
secara default ditetapkan ke 0,45.
Ini adalah properti global, sehingga akan mengubah semua kolom dropdown saat disetel.
Pencocokan awalan/akhiran
Jika semua opsi menu dropdown memiliki awalan dan/atau akhiran yang sama, kata-kata ini akan otomatis dikeluarkan dan dimasukkan sebagai teks statis. Misalnya, berikut dua cara untuk membuat blok yang sama (yang pertama tanpa pencocokan akhiran, dan yang kedua dengan pencocokan akhiran):
Tanpa pencocokan akhiran:
JSON
{
"type": "dropdown_no_matching",
"message0": "hello %1",
"args0": [
{
"type": "field_dropdown",
"name": "MODE",
"options": [
["world", "WORLD"],
["computer", "CPU"]
]
}
]
}
JavaScript
Blockly.Blocks['dropdown_no_matching'] = {
init: function() {
var options = [
['world', 'WORLD'],
['computer', 'CPU']
];
this.appendDummyInput()
.appendField('hello')
.appendField(new Blockly.FieldDropdown(options), 'MODE');
}
};
Dengan pencocokan akhiran:
JSON
{
"type": "dropdown_with_matching",
"message0": "%1",
"args0": [
{
"type": "field_dropdown",
"name": "MODE",
"options": [
["hello world", "WORLD"],
["hello computer", "CPU"]
]
}
]
}
JavaScript
Blockly.Blocks['dropdown_with_matching'] = {
init: function() {
var options = [
['hello world', 'WORLD'],
['hello computer', 'CPU']
];
this.appendDummyInput()
.appendField(new Blockly.FieldDropdown(options), 'MODE');
}
};
Salah satu keuntungan dari pendekatan ini adalah bahwa blok lebih mudah diterjemahkan ke dalam
bahasa lain. Kode sebelumnya memiliki string 'hello'
, 'world'
, dan
'computer'
, sedangkan kode yang direvisi memiliki string 'hello world'
dan
'hello computer'
. Penerjemah akan lebih mudah menerjemahkan frasa daripada
kata-kata yang terpisah.
Keuntungan lain dari pendekatan ini adalah urutan kata sering berubah di antara
bahasa. Bayangkan bahasa yang menggunakan 'world hello'
dan 'computer hello'
.
Algoritma pencocokan akhiran akan mendeteksi 'hello'
yang umum dan menampilkannya
setelah menu drop-down.
Namun, terkadang pencocokan awalan/akhiran gagal. Ada beberapa kasus di mana dua kata harus selalu digabungkan dan awalan tidak boleh dikeluarkan.
Misalnya, 'drive red car'
dan 'drive red truck'
bisa dibilang hanya
memiliki 'drive'
yang dikeluarkan, bukan 'drive red'
. Spasi tidak terputus Unicode '\u00A0'
dapat digunakan sebagai pengganti spasi biasa untuk menekan pencocokan awalan/akhiran. Jadi, contoh di atas dapat diperbaiki dengan
'drive red\u00A0car'
dan 'drive red\u00A0truck'
.
Tempat lain yang menyebabkan pencocokan awalan/akhiran gagal adalah dalam bahasa yang tidak memisahkan setiap kata dengan spasi. Bahasa China adalah contoh yang baik. String
'訪問中國'
berarti 'visit China'
, perhatikan tidak adanya spasi di antara kata.
Secara bersama-sama, dua karakter terakhir ('中國'
) adalah kata untuk 'China'
,
tetapi jika dipisah, keduanya akan berarti 'centre'
dan 'country'
. Agar pencocokan awalan/akhiran berfungsi dalam bahasa seperti China, cukup sisipkan spasi di tempat jeda seharusnya berada. Misalnya, '訪問 中國'
dan
'訪問 美國'
akan menghasilkan "visit [China/USA]"
, sedangkan '訪問 中 國'
dan
'訪問 美 國'
akan menghasilkan "visit [centre/beautiful] country"
.
Membuat validator dropdown
Nilai kolom dropdown adalah string netral bahasa, sehingga validator apa pun harus menerima string dan menampilkan string yang merupakan opsi yang tersedia, null
, atau undefined
.
Jika validator Anda menampilkan hal lain, perilaku Blockly tidak ditentukan dan program Anda mungkin error.
Misalnya, Anda dapat menentukan kolom dropdown dengan tiga opsi dan validator seperti ini:
validate: function(newValue) {
this.getSourceBlock().updateConnections(newValue);
return newValue;
},
init: function() {
var options = [
['has neither', 'NEITHER'],
['has statement', 'STATEMENT'],
['has value', 'VALUE'],
];
this.appendDummyInput()
// Pass the field constructor the options list, the validator, and the name.
.appendField(new Blockly.FieldDropdown(options, this.validate), 'MODE');
}
validate
selalu menampilkan nilai yang diteruskan, tetapi memanggil fungsi
pembantu updateConnection
yang menambahkan atau menghapus input berdasarkan nilai
dropdown:
updateConnections: function(newValue) {
this.removeInput('STATEMENT', /* no error */ true);
this.removeInput('VALUE', /* no error */ true);
if (newValue == 'STATEMENT') {
this.appendStatementInput('STATEMENT');
} else if (newValue == 'VALUE') {
this.appendValueInput('VALUE');
}
}