The ComboBox menu can now be filtered by typing.

This commit is contained in:
Daan Vanden Bosch 2019-09-14 13:16:13 +02:00
parent c8ff72726e
commit 58939b2ff5
3 changed files with 38 additions and 3 deletions

View File

@ -10,8 +10,9 @@ import { WidgetProperty } from "../observable/property/WidgetProperty";
export type ComboBoxOptions<T> = LabelledControlOptions & {
items: T[] | Property<T[]>;
to_label: (item: T) => string;
to_label(item: T): string;
placeholder_text?: string;
filter?(text: string): void;
};
export class ComboBox<T> extends LabelledControl {
@ -41,6 +42,7 @@ export class ComboBox<T> extends LabelledControl {
this.input_element.onmousedown = () => {
menu_visible.val = true;
};
this.input_element.onkeydown = (e: Event) => {
const key = (e as KeyboardEvent).key;
@ -60,6 +62,24 @@ export class ComboBox<T> extends LabelledControl {
break;
}
};
const filter = options.filter;
if (filter) {
let input_value = "";
this.input_element.onkeyup = () => {
if (this.input_element.value !== input_value) {
input_value = this.input_element.value;
filter(input_value);
if (this.menu.visible.val || input_value) {
this.menu.hover_next();
}
}
};
}
this.input_element.onblur = () => {
menu_visible.val = false;
};
@ -92,6 +112,12 @@ export class ComboBox<T> extends LabelledControl {
this.disposables(
this.menu.visible.bind_bi(menu_visible),
menu_visible.observe(({ value: visible }) => {
if (visible) {
this.menu.hover_next();
}
}),
this.menu.selected.observe(({ value }) => {
this.selected.set_val(value, { silent: false });
this.input_element.focus();

View File

@ -48,6 +48,7 @@ export class Menu<T> extends Widget {
el.div({ text: to_label(item), data: { index: index.toString() } }),
),
);
this.hover_item();
},
{ call_now: true },
),
@ -83,7 +84,7 @@ export class Menu<T> extends Widget {
if (this.visible.val != visible) {
this.hover_item();
this.inner_element.scrollTo(0, 0);
this.inner_element.scrollTop = 0;
}
}

View File

@ -23,12 +23,19 @@ export class WantedItemsView extends Widget {
super(el.div({ class: "hunt_optimizer_WantedItemsView" }));
const huntable_items = list_property<ItemType>();
const filtered_huntable_items = list_property<ItemType>();
const combo_box = this.disposable(
new ComboBox({
items: huntable_items,
items: filtered_huntable_items,
to_label: item_type => item_type.name,
placeholder_text: "Add an item",
filter(text: string): void {
const text_lower = text.toLowerCase();
filtered_huntable_items.val = huntable_items.val.filter(item_type =>
item_type.name.toLowerCase().includes(text_lower),
);
},
}),
);
@ -60,6 +67,7 @@ export class WantedItemsView extends Widget {
huntable_items.val = hunt_optimizer_store.huntable_item_types
.slice()
.sort((a, b) => a.name.localeCompare(b.name));
filtered_huntable_items.val = huntable_items.val;
},
{ call_now: true },
),