يخزِّن الحقل المنسدلة سلسلة كنصّه وسلسلة كقيمة له. القيمة هي مفتاح محايد من حيث اللغة سيتم استخدامه للوصول إلى النص، ولن تتم ترجمته عند تبديل Blockly بين اللغات. النص هو سلسلة يمكن لشخص عادي قراءتها وسيتم عرضها على المستخدم.
حقل القائمة المنسدلة
حقل منسدل مع فتح المحرِّر
حقل قائمة منسدلة في القسم المصغّر
الإنشاء
يأخذ مُنشئ القائمة المنسدلة مُنشئ قائمة وأداة التحقّق اختيارية. يتمتع أداة إنشاء القوائم بقدرٍ كبير من المرونة، ولكنها في الأساس مصفوفة من الخيارات، يحتوي كل خيار منها على جزء يسهل قراءته وسلسلة محايدة من حيث اللغة.
القوائم المنسدلة النصية البسيطة
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');
}
};
إنّ فصل المعلومات القابلة للقراءة عن المفتاح المحايد من حيث اللغة
يسمح بحفظ إعدادات القائمة المنسدلة بين اللغات. على سبيل المثال، قد تحدّد النسخة الإنجليزية من أحد الكتل [['left', 'LEFT'], ['right',
'RIGHT]]
بينما تحدّد النسخة الألمانية من الكتلة نفسها [['links',
'LEFT'], ['rechts', 'RIGHT]]
.
القوائم المنسدلة للصور
قد تكون الخيارات في القائمة المنسدلة صورًا أيضًا بدلاً من نص. يتم تحديد عناصر الصور
باستخدام السمات src
وwidth
وheight
و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');
}
};
القوائم المنسدلة الديناميكية
JSON
{
"type": "dynamic_dropdown",
"message0": "day %1",
"args0": [
{
"type": "input_dummy",
"name": "INPUT"
}
],
"extensions": ["dynamic_menu_extension"]
}
Blockly.Extensions.register('dynamic_menu_extension',
function() {
this.getInput('INPUT')
.appendField(new Blockly.FieldDropdown(
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;
}), 'DAY');
});
ويتم ذلك باستخدام إضافة ملف 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;
}
};
يمكن أيضًا توفير قائمة منسدلة باستخدام دالة بدلاً من قائمة بالخيارات الثابتة، ما يسمح بجعل الخيارات ديناميكية. يجب أن تعرِض الدالة [human-readable-value, language-neutral-key]
صفيفًا من الخيارات بالتنسيق نفسه [human-readable-value, language-neutral-key]
للخيارات الثابتة. في كل مرة يتم فيها النقر على القائمة المنسدلة، يتم تنفيذ الدالة ويعاد احتساب الخيارات.
الفواصل
استخدِم السلسلة 'separator'
لإضافة خط بين الخيارات في قائمة منسدلة.
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");
}
};
نشر الحلقات على نحو متسلسِل
JSON
يظهر تنسيق JSON الخاص بحقل القائمة المنسدلة على النحو التالي:
{
"fields": {
"FIELDNAME": "LANGUAGE-NEUTRAL-KEY"
}
}
حيث يكون FIELDNAME
سلسلة تشير إلى حقل قائمة منسدلة، و
القيمة هي القيمة التي سيتم تطبيقها على الحقل. يجب أن تكون القيمة مفتاح خيار
غير متحيّز للغة.
XML
يظهر تنسيق XML الخاص بحقل القائمة المنسدلة على النحو التالي:
<field name="FIELDNAME">LANGUAGE-NEUTRAL-KEY</field>
حيث تحتوي سمة name
للحقل على سلسلة تشير إلى حقل Dropdown
، والنص الداخلي هو القيمة التي سيتم تطبيقها على الحقل. يجب أن يكون
النص الداخلي مفتاح خيار صالحًا ومحايدًا من حيث اللغة.
التخصيص
سهم القائمة المنسدلة
يمكن استخدام السمة Blockly.FieldDropdown.ARROW_CHAR
لتغيير
حرف اليونيكود الذي يمثّل سهم القائمة المنسدلة.
تكون السمة ARROW_CHAR
تلقائيًا \u25BC
(▼) على Android و\u25BE
(▾)
بخلاف ذلك.
هذا سمة عامة، لذا سيُعدّل جميع الحقول المنسدلة عند ضبطه.
ارتفاع القائمة
يمكن استخدام السمة Blockly.FieldDropdown.MAX_MENU_HEIGHT_VH
لتغيير
الحد الأقصى للارتفاع في القائمة. ويتم تعريفه كنسبة مئوية من ارتفاع إطار العرض، ويكون إطار العرض هو النافذة.
تكون القيمة التلقائية لسمة MAX_MENU_HEIGHT_VH
هي 0.45.
هذا سمة عامة، لذا ستُعدّل جميع الحقول المنسدلة عند ضبطها.
مطابقة البادئة/اللاحقة
إذا كانت جميع خيارات القائمة المنسدلة تتشارك كلمات بادئة و/أو لاحقة شائعة، يتم استبعاد هذه الكلمات تلقائيًا وإدراجها كنص ثابت. على سبيل المثال، إليك طريقتان لإنشاء الكتلة نفسها (هذه الأولى بدون مطابقة اللاحقة، والثانية مع):
بدون مطابقة اللاحقة:
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');
}
};
باستخدام مطابقة اللاحقة:
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');
}
};
من مزايا هذا الأسلوب أنّه من الأسهل ترجمة القسم إلى
لغات أخرى. يتضمّن الرمز السابق السلاسل 'hello'
و'world'
و
'computer'
، في حين يتضمّن الرمز المعدَّل السلاسل 'hello world'
و
'hello computer'
. يجد المترجمون أنّ ترجمة العبارات أسهل بكثير من ترجمة
الكلمات بشكل منفصل.
ومن المزايا الأخرى لهذا النهج أنّ ترتيب الكلمات يتغيّر غالبًا بين
اللغات. تخيل لغة تستخدم 'world hello'
و'computer hello'
.
سترصد خوارزمية مطابقة اللاحقة 'hello'
الشائعة وتعرضها
بعد القائمة المنسدلة.
ومع ذلك، قد يتعذّر أحيانًا مطابقة البادئة/اللاحقة. هناك بعض الحالات التي ينبغي فيها استخدام
كلمتَين معًا دائمًا وعدم استبعاد البادئة.
على سبيل المثال، يمكن القول إنّه يجب
استبعاد 'drive'
فقط من 'drive red car'
و'drive red truck'
، وليس 'drive red'
. يمكن استخدام المساحة غير القابلة للانقطاع '\u00A0'
في يونيكود بدلاً من المساحة العادية لإيقاف مطابقة البادئة/اللاحقة. وبالتالي، يمكن إصلاح المثال أعلاه باستخدام
'drive red\u00A0car'
و'drive red\u00A0truck'
.
لا يمكن أيضًا مطابقة البادئة/اللاحقة في اللغات التي لا تُميز
بين الكلمات الفردية باستخدام المسافات. واللغة الصينية هي مثال جيد على ذلك. تشير السلسلة
'訪問中國'
إلى 'visit China'
، مع ملاحظة عدم وجود مسافات بين الكلمات.
يشكّل الحرفان الأخيران ('中國'
) معًا كلمة 'China'
،
ولكن في حال تقسيمهما، سيعنيان 'centre'
و'country'
على التوالي. لكي تعمل ميزة مطابقة البادئة/اللاحقة في لغات مثل الصينية،
ما عليك سوى إدراج مسافة في المكان الذي يجب أن يكون فيه الفاصل. على سبيل المثال، سيؤدي الجمع بين '訪問 中國'
و
'訪問 美國'
إلى "visit [China/USA]"
، في حين سيؤدي الجمع بين '訪問 中 國'
و
'訪問 美 國'
إلى "visit [centre/beautiful] country"
.
إنشاء أداة التحقّق من القائمة المنسدلة
قيمة حقل القائمة المنسدلة هي سلسلة محايدة لغويًا، لذا يجب أن يقبل أيّ مدقّق صحة
سلسلة ويعرض سلسلة تمثل خيارًا متاحًا أو null
أو
undefined
.
إذا عرض مدقّق الصحة أي شيء آخر، سيكون سلوك Blockly غير محدّد وقد يؤدي ذلك إلى تعطُّل البرنامج.
على سبيل المثال، يمكنك تحديد حقل منسدل يتضمّن ثلاثة خيارات وأحد أدوات التحقّق التالية:
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
دائمًا القيمة التي تم تمريرها إليها، ولكنها تستدعي الدالة المساعِدة
updateConnection
التي تضيف مدخلات أو تزيلها استنادًا إلى قيمة القائمة المنسدلة:
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');
}
}