ช่องรายการแบบเลื่อนลง

ช่องแบบเลื่อนลงจะเก็บสตริงเป็นค่าและสตริงเป็นข้อความ value คือคีย์กลางทางภาษาที่จะใช้ในการเข้าถึงข้อความและ จะไม่ได้รับการแปลเมื่อ Blockly สลับระหว่างภาษา ข้อความคือ สตริงที่มนุษย์อ่านได้ซึ่งจะแสดงต่อผู้ใช้

การสร้างวิดีโอ

เครื่องมือสร้างเมนูแบบเลื่อนลงจะใช้โปรแกรมสร้างเมนูและ โปรแกรมตรวจสอบ โปรแกรมสร้างเมนูมี ความยืดหยุ่น แต่โดยพื้นฐานแล้วจะเป็นอาร์เรย์ตัวเลือก โดยแต่ละตัวเลือกที่มี ส่วนที่มนุษย์อ่านได้ และสตริงที่เป็นกลางทางภาษา

เมนูแบบเลื่อนลงที่เป็นข้อความธรรมดา

เปิดเมนูแบบเลื่อนลงที่มีตัวเลือกข้อความ 2 ตัวเลือก

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] เดียวกัน เป็นรูปแบบคงที่ ทุกครั้งที่มีการคลิกเมนูแบบเลื่อนลง ฟังก์ชันจะ เรียกใช้ แล้วระบบจะคำนวณตัวเลือกใหม่

การเรียงอันดับ

JSON

JSON สำหรับช่องแบบเลื่อนลงมีลักษณะดังนี้

{
  "fields": {
    "FIELDNAME": "LANGUAGE-NEUTRAL-KEY"
  }
}

โดยที่ FIELDNAME คือสตริงที่อ้างอิงช่องเมนูแบบเลื่อนลง และ value คือค่าที่จะใช้กับฟิลด์ ค่าควรเป็น คีย์ตัวเลือกภาษากลาง

XML

XML สำหรับช่องแบบเลื่อนลงมีลักษณะดังนี้

<field name="FIELDNAME">LANGUAGE-NEUTRAL-KEY</field>

เมื่อแอตทริบิวต์ name ของช่องมีสตริงที่อ้างอิงเมนูแบบเลื่อนลง และข้อความด้านในคือค่าที่จะใช้กับฟิลด์ โครงสร้างภายใน ควรเป็นคีย์ตัวเลือกภาษากลางที่ถูกต้อง

การปรับแต่ง

คุณใช้พร็อพเพอร์ตี้ Blockly.FieldDropdown.ARROW_CHAR เพื่อเปลี่ยน อักขระ Unicode ที่แสดงลูกศรแบบเลื่อนลง

ช่องรายการแบบเลื่อนลงมีลูกศรที่กำหนดเอง

พร็อพเพอร์ตี้ ARROW_CHAR มีค่าเริ่มต้นเป็น \u25BC (▼) ใน Android และ \u25BE (▾) หรือไม่เช่นนั้น

นี่เป็นพร็อพเพอร์ตี้ส่วนกลาง จึงจะแก้ไขช่องแบบเลื่อนลงทั้งหมดเมื่อตั้งค่า

ใช้พร็อพเพอร์ตี้ Blockly.FieldDropdown.MAX_MENU_HEIGHT_VH เพื่อเปลี่ยน ความสูงสูงสุดของเมนู โดยกำหนดเป็นเปอร์เซ็นต์ของวิวพอร์ต ความสูงเท่าใด วิวพอร์ตที่เป็นหน้าต่าง

พร็อพเพอร์ตี้ MAX_MENU_HEIGHT_VH จะมีค่าเริ่มต้นเป็น 0.45

นี่เป็นพร็อพเพอร์ตี้ส่วนกลาง จึงจะแก้ไขช่องแบบเลื่อนลงทั้งหมดเมื่อตั้งค่า

การจับคู่คำนำหน้า/คำต่อท้าย

หากตัวเลือกของเมนูแบบเลื่อนลงทั้งหมดใช้คำนำหน้าและ/หรือคำต่อท้ายร่วมกัน คำเหล่านี้ คำเหล่านี้จะถูกแยกตัวออกมาและแทรกเป็นข้อความแบบคงที่โดยอัตโนมัติ ตัวอย่างเช่น คุณสามารถสร้างบล็อกเดียวกันได้ 2 วิธี (วิธีแรกคือ การจับคู่ส่วนต่อท้าย และคำที่สองคือ):

เมื่อไม่มีการจับคู่ส่วนต่อท้าย:

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 red car' และ 'drive red truck' ควรโต้แย้งได้เฉพาะ แยก 'drive' ไว้ ไม่ใช่ 'drive red' Unicode แบบไม่ขาดตอน สามารถใช้พื้นที่ทำงาน '\u00A0' แทนพื้นที่ทำงานปกติเพื่อระงับพร็อพเพอร์ตี้ ตัวจับคู่คำนำหน้า/คำต่อท้าย ดังนั้นตัวอย่างข้างต้นสามารถแก้ไขได้ด้วย 'drive red\u00A0car' และ 'drive red\u00A0truck'

อีกที่หนึ่งที่การจับคู่คำนำหน้า/คำต่อท้ายไม่สำเร็จคือภาษาที่ไม่มี คั่นแต่ละคำด้วยการเว้นวรรค ภาษาจีนเป็นตัวอย่างที่ดี สตริง '訪問中國' หมายถึง 'visit China' โปรดสังเกตว่าไม่มีการเว้นวรรคระหว่างคำ โดยรวมแล้ว อักขระสองตัวสุดท้าย ('中國') คือคำของ 'China' แต่หากแบ่ง จะหมายถึง 'centre' และ 'country' ตามลำดับ เพื่อให้ การจับคู่คำนำหน้า/คำต่อท้ายใช้ได้ในภาษาต่างๆ เช่น จีน เพียงแค่แทรกช่องว่างที่ควรจะเป็น เช่น '訪問 中國' และ '訪問 美國' จะได้ผลลัพธ์เป็น "visit [China/USA]" ในขณะที่ '訪問 中 國' และ '訪問 美 國' จะทำให้เป็น "visit [centre/beautiful] country"

การสร้างโปรแกรมตรวจสอบเมนูแบบเลื่อนลง

ค่าของช่องรายการแบบเลื่อนลงจะเป็นสตริงที่เป็นกลางทางภาษา ดังนั้นโปรแกรมตรวจสอบจะต้อง ยอมรับสตริงและแสดงผลสตริง ที่มีตัวเลือกที่ใช้ได้, null หรือ undefined

หากโปรแกรมตรวจสอบของคุณส่งคืนผลลัพธ์ใดๆ เพิ่มเติม แสดงว่าไม่มีการกำหนดลักษณะการทำงานของ Blockly โปรแกรมของคุณอาจขัดข้องได้

ตัวอย่างเช่น คุณสามารถกำหนดช่องแบบเลื่อนลงให้มี 3 ตัวเลือกและ ดังนี้

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 จะแสดงผลค่าที่ส่งไปแล้วเสมอ แต่จะเรียก Assistant ว่า ฟังก์ชัน 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');
  }
}