Skip to content

Commit a2d7621

Browse files
authored
Feature: Add a dropdown options setter (#8833)
* Feature: Add a setOptions method to field_dropdown * add test for changing droopdown options * split out setOptions tests into their own test suite * Add additional tests * auto format files
1 parent 5df6284 commit a2d7621

File tree

2 files changed

+69
-16
lines changed

2 files changed

+69
-16
lines changed

core/field_dropdown.ts

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -136,26 +136,11 @@ export class FieldDropdown extends Field<string> {
136136
// If we pass SKIP_SETUP, don't do *anything* with the menu generator.
137137
if (menuGenerator === Field.SKIP_SETUP) return;
138138

139-
if (Array.isArray(menuGenerator)) {
140-
this.validateOptions(menuGenerator);
141-
const trimmed = this.trimOptions(menuGenerator);
142-
this.menuGenerator_ = trimmed.options;
143-
this.prefixField = trimmed.prefix || null;
144-
this.suffixField = trimmed.suffix || null;
145-
} else {
146-
this.menuGenerator_ = menuGenerator;
147-
}
148-
149-
/**
150-
* The currently selected option. The field is initialized with the
151-
* first option selected.
152-
*/
153-
this.selectedOption = this.getOptions(false)[0];
139+
this.setOptions(menuGenerator);
154140

155141
if (config) {
156142
this.configure_(config);
157143
}
158-
this.setValue(this.selectedOption[1]);
159144
if (validator) {
160145
this.setValidator(validator);
161146
}
@@ -414,6 +399,28 @@ export class FieldDropdown extends Field<string> {
414399
return this.generatedOptions;
415400
}
416401

402+
/**
403+
* Update the options on this dropdown. This will reset the selected item to
404+
* the first item in the list.
405+
*
406+
* @param menuGenerator The array of options or a generator function.
407+
*/
408+
setOptions(menuGenerator: MenuGenerator) {
409+
if (Array.isArray(menuGenerator)) {
410+
this.validateOptions(menuGenerator);
411+
const trimmed = this.trimOptions(menuGenerator);
412+
this.menuGenerator_ = trimmed.options;
413+
this.prefixField = trimmed.prefix || null;
414+
this.suffixField = trimmed.suffix || null;
415+
} else {
416+
this.menuGenerator_ = menuGenerator;
417+
}
418+
// The currently selected option. The field is initialized with the
419+
// first option selected.
420+
this.selectedOption = this.getOptions(false)[0];
421+
this.setValue(this.selectedOption[1]);
422+
}
423+
417424
/**
418425
* Ensure that the input value is a valid language-neutral option.
419426
*

tests/mocha/field_dropdown_test.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,52 @@ suite('Dropdown Fields', function () {
195195
assertFieldValue(this.field, 'B', 'b');
196196
});
197197
});
198+
suite('setOptions', function () {
199+
setup(function () {
200+
this.field = new Blockly.FieldDropdown([
201+
['a', 'A'],
202+
['b', 'B'],
203+
['c', 'C'],
204+
]);
205+
});
206+
test('With array updates options', function () {
207+
this.field.setOptions([
208+
['d', 'D'],
209+
['e', 'E'],
210+
['f', 'F'],
211+
]);
212+
assertFieldValue(this.field, 'D', 'd');
213+
});
214+
test('With generator updates options', function () {
215+
this.field.setOptions(function () {
216+
return [
217+
['d', 'D'],
218+
['e', 'E'],
219+
['f', 'F'],
220+
];
221+
});
222+
assertFieldValue(this.field, 'D', 'd');
223+
});
224+
test('With trimmable options gets trimmed', function () {
225+
this.field.setOptions([
226+
['a d b', 'D'],
227+
['a e b', 'E'],
228+
['a f b', 'F'],
229+
]);
230+
assert.deepEqual(this.field.prefixField, 'a');
231+
assert.deepEqual(this.field.suffixField, 'b');
232+
assert.deepEqual(this.field.getOptions(), [
233+
['d', 'D'],
234+
['e', 'E'],
235+
['f', 'F'],
236+
]);
237+
});
238+
test('With an empty array of options throws', function () {
239+
assert.throws(function () {
240+
this.field.setOptions([]);
241+
});
242+
});
243+
});
198244

199245
suite('Validators', function () {
200246
setup(function () {

0 commit comments

Comments
 (0)