ड्रॉपडाउन फ़ील्ड

ड्रॉपडाउन फ़ील्ड, अपनी वैल्यू के तौर पर एक स्ट्रिंग और अपने टेक्स्ट के तौर पर एक स्ट्रिंग सेव करता है. यह वैल्यू, भाषा से जुड़ी जानकारी के बिना इस्तेमाल की जाने वाली कुंजी है. इसका इस्तेमाल टेक्स्ट को ऐक्सेस करने के लिए किया जाएगा. साथ ही, Blockly को एक भाषा से दूसरी भाषा में स्विच करने पर इसका अनुवाद नहीं किया जाएगा. यह टेक्स्ट, ऐसी स्ट्रिंग होती है जिसे कोई भी व्यक्ति आसानी से पढ़ सकता है. यह स्ट्रिंग, उपयोगकर्ता को दिखाई जाएगी.

"ड्रॉप-डाउन:" लेबल वाला ब्लॉक, "पहला" चुना गया ड्रॉपडाउन फ़ील्ड, और "आइटम" लेबल.

ड्रॉपडाउन खुला होने पर, ब्लॉक का वही हिस्सा. ड्रॉपडाउन में "first"
और "second" आइटम शामिल हैं.

कोलैप्स किए जाने के बाद वही ब्लॉक. इसमें "ड्रॉप-डाउन: पहला आइटम" लेबल है. साथ ही, इसे छोटा करके दिखाने के लिए, दाईं ओर का किनारा कटा-फटा है.

कॉन्टेंट बनाने के

ड्रॉपडाउन कंस्ट्रक्टर, मेन्यू जनरेटर और मान्य करने वाले को इनपुट के तौर पर लेता है. हालांकि, मान्य करने वाले को इनपुट के तौर पर लेना ज़रूरी नहीं है. मेन्यू जनरेटर, विकल्पों की एक ऐसी सूची होती है जिसमें हर विकल्प में, इंसानों के पढ़ने लायक एक हिस्सा और भाषा से जुड़ी जानकारी के बिना एक स्ट्रिंग होती है. इसके अलावा, यह विकल्पों की सूची जनरेट करने वाला एक फ़ंक्शन भी हो सकता है. हर विकल्प का ऐसा हिस्सा जिसे आसानी से पढ़ा जा सकता है, वह स्ट्रिंग, इमेज या एचटीएमएल एलिमेंट हो सकता है. साथ ही, ऐरे में अलग-अलग तरह के विकल्पों का कॉम्बिनेशन हो सकता है.

सिंपल टेक्स्ट ड्रॉपडाउन

टेक्स्ट के दो विकल्पों वाला ड्रॉपडाउन खोलें

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');
  }
};

एचटीएमएल ड्रॉपडाउन

कोई विकल्प, कोई भी एचटीएमएल एलिमेंट हो सकता है. हालांकि, यह बहुत बड़ा नहीं होना चाहिए और इसमें माउस या कीबोर्ड इवेंट को हैंडल करने की कोशिश नहीं की जानी चाहिए. (इन नियमों का पालन करना आपकी ज़िम्मेदारी है. Blockly इन्हें लागू नहीं करता.)

ड्रॉपडाउन खुला होने पर, सूची में एचटीएमएल एलिमेंट दिखता है. जब यह बंद हो और एलिमेंट को चुने गए विकल्प के तौर पर इस्तेमाल किया जा रहा हो, तब सूची में एलिमेंट का title एट्रिब्यूट, उसका aria-label एट्रिब्यूट या उसकी 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);
  });

इसके लिए, 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');
  }
};

डाइनैमिक ड्रॉपडाउन

हफ़्ते के दिनों वाला ड्रॉपडाउन फ़ील्ड

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;
      });
  });

इसके लिए, 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] फ़ॉर्मैट में हो. ड्रॉपडाउन पर क्लिक करने पर, फ़ंक्शन हर बार चलता है और विकल्पों की फिर से गिनती की जाती है.

सेपरेटर

ड्रॉपडाउन मेन्यू में विकल्पों के बीच लाइन जोड़ने के लिए, '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

ड्रॉपडाउन फ़ील्ड के लिए एक्सएमएल ऐसा दिखता है:

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

यहां फ़ील्ड के name एट्रिब्यूट में, ड्रॉपडाउन फ़ील्ड का रेफ़रंस देने वाली स्ट्रिंग मौजूद होती है. साथ ही, इनर टेक्स्ट वह वैल्यू होती है जिसे फ़ील्ड पर लागू करना होता है. इनर टेक्स्ट, भाषा से जुड़ी सेटिंग के लिए मान्य विकल्प कुंजी होनी चाहिए.

कस्टमाइज़ेशन

Blockly.FieldDropdown.ARROW_CHAR प्रॉपर्टी का इस्तेमाल, ड्रॉपडाउन ऐरो को दिखाने वाले यूनिकोड वर्ण को बदलने के लिए किया जा सकता है.

कस्टम ऐरो वाला ड्रॉपडाउन फ़ील्ड

Android पर ARROW_CHAR प्रॉपर्टी की डिफ़ॉल्ट वैल्यू \u25BC (▼) होती है. वहीं, अन्य प्लैटफ़ॉर्म पर इसकी डिफ़ॉल्ट वैल्यू \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 red car' और 'drive red truck' में सिर्फ़ 'drive' को शामिल किया जाना चाहिए, न कि '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');
  }
}

ऐनिमेटेड GIF में, ड्रॉपडाउन फ़ील्ड दिखाया गया है. इसमें तीन आइटम हैं: &quot;न तो&quot;, &quot;स्टेटमेंट&quot;, और &quot;वैल्यू&quot;. &quot;इनमें से कोई नहीं&quot; विकल्प चुनने पर, कोई इनपुट नहीं होता है. &quot;statement&quot; चुने जाने पर, इसमें स्टेटमेंट इनपुट होता है. जब &quot;वैल्यू&quot; कनेक्ट होती है, तो इसमें &quot;वैल्यू&quot; इनपुट होता है.