プルダウン フィールド

プルダウン フィールドには、文字列を値として、文字列をテキストとして保存します。この値は言語に依存しないキーです。テキストへのアクセスに使用され、Blockly が言語を切り替えても翻訳されることはありません。このテキストは、ユーザーに表示される、人が読める形式の文字列です。

動画を作成

プルダウン コンストラクタは、メニュー ジェネレータとオプションのvalidatorを受け取ります。メニュー ジェネレータには多くの柔軟性がありますが、基本的にはオプションの配列であり、各オプションには人間が読める部分と、言語に依存しない文字列が含まれています。

シンプルなテキスト プルダウン

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]] が定義されます。

画像のプルダウン

プルダウン メニューのオプションは、テキストではなく画像にすることもできます。画像オブジェクトは、srcwidthheightalt プロパティで指定します。

プルダウンにはテキスト オプションと画像オプションを混在させることができますが、現在のところ、個々のオプションに画像とテキストの両方を含めることはできません。

画像とテキストを含むプルダウン フィールド

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 はプルダウン フィールドを参照する文字列、値はフィールドに適用する値です。値は言語に依存しないオプションキーにする必要があります。

XML

プルダウン フィールドの XML は次のようになります。

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

ここで、フィールドの name 属性にはプルダウン フィールドを参照する文字列が含まれ、内側のテキストはフィールドに適用する値です。内部テキストは、言語に依存しない有効なオプションキーにする必要があります。

カスタマイズ

Blockly.FieldDropdown.ARROW_CHAR プロパティを使用すると、プルダウン矢印を表す Unicode 文字を変更できます。

カスタム矢印の付いたプルダウン フィールド

ARROW_CHAR プロパティのデフォルトは、Android の場合は \u25BC(▼)、それ以外の場合は \u25BE(▾)です。

これはグローバル プロパティであるため、設定するとすべてのプルダウン フィールドが変更されます。

Blockly.FieldDropdown.MAX_MENU_HEIGHT_VH プロパティを使用すると、メニューの最大の高さを変更できます。この値は、ビューポートの高さに対する割合として定義されます(ビューポートはウィンドウです)。

MAX_MENU_HEIGHT_VH プロパティのデフォルトは 0.45 です。

これはグローバル プロパティであるため、設定するとすべてのプルダウン フィールドが変更されます。

接頭辞/接尾辞のマッチング

すべてのプルダウン メニュー オプションが共通の接頭辞/接尾辞の単語を共有している場合、これらの単語は自動的に除外され、静的テキストとして挿入されます。たとえば、同じブロックを作成する 2 つの方法を以下に示します(1 つ目はサフィックス マッチングなしで、2 つ目はサフィックス マッチングありで、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');
  }
};

次のフィールドを含むプルダウン フィールド

この方法の利点の 1 つは、ブロックを他の言語に翻訳しやすいことです。前のコードには 'hello''world''computer' という文字列がありますが、改訂されたコードには 'hello world''hello computer' という文字列があります。翻訳者は、単語を単独で使用するよりも、フレーズを翻訳するほうがはるかに簡単です。

このアプローチのもう 1 つの利点は、言語間で語順が頻繁に変わることです。ある言語に 'world hello''computer hello' が使用されているとします。サフィックス マッチング アルゴリズムは、一般的な 'hello' を検出し、プルダウンの後に表示します。

ただし、プレフィックスやサフィックスの照合が失敗することもあります。場合によっては、2 つの単語を常に一緒に使用し、接頭辞は除外しないでください。たとえば 'drive red car''drive red truck' については、ほぼ間違いなく、'drive red' ではなく 'drive' のみが除外されます。通常のスペースの代わりに Unicode の改行なしスペース '\u00A0' を使用すると、プレフィックス/サフィックス マッチャーを抑制できます。したがって、上記の例は 'drive red\u00A0car''drive red\u00A0truck' で修正できます。

また、個々の単語がスペースで区切られていない言語でも、接頭辞や接尾辞の照合が失敗します。中国語が良い例です。文字列 '訪問中國''visit China' を意味します。単語間にスペースがないことに注意してください。総称して、最後の 2 文字('中國')は '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 は常に渡された値を返しますが、プルダウン値に基づいて入力を追加または削除するヘルパー関数 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');
  }
}