UNPKG

@bokeh/bokehjs

Version:

Interactive, novel data visualization

106 lines 3.39 kB
import { select, option, optgroup, empty } from "../../core/dom"; import { isString, isArray } from "../../core/util/types"; import { entries } from "../../core/util/object"; import { InputWidget, InputWidgetView } from "./input_widget"; import * as inputs from "../../styles/widgets/inputs.css"; import { Unknown, Str, List, Tuple, Or, Dict } from "../../core/kinds"; const Value = Unknown; const Label = Str; const Options = List(Or(Label, Tuple(Value, Label))); const OptionsGroups = Dict(Options); const NotSelected = ""; export class SelectView extends InputWidgetView { static __name__ = "SelectView"; connect_signals() { super.connect_signals(); const { value, options } = this.model.properties; this.on_change(value, () => { this._update_value(); }); this.on_change(options, () => { empty(this.input_el); this.input_el.append(...this.options_el()); this._update_value(); }); } _known_values = new Map(); options_el() { const { _known_values } = this; _known_values.clear(); function build_options(values) { return values.map((el) => { let value, label; if (isString(el)) { value = label = el; } else { [value, label] = el; } _known_values.set(value, label); return option({ value: label }, label); }); } const { options } = this.model; if (isArray(options)) { return build_options(options); } else { return entries(options).map(([label, values]) => optgroup({ label }, build_options(values))); } } _render_input() { this.input_el = select({ class: inputs.input, name: this.model.name, disabled: this.model.disabled, }, this.options_el()); this.input_el.addEventListener("change", () => this.change_input()); return this.input_el; } render() { super.render(); this._update_value(); } change_input() { const selected_label = this.input_el.value; const found = [...this._known_values].find(([_, label]) => selected_label == label); const value = (() => { if (found == null) { return NotSelected; } else { const [value, _] = found; return value; } })(); this.model.value = value; super.change_input(); } _update_value() { const { value } = this.model; const label = this._known_values.get(value); if (label !== undefined) { this.input_el.value = label; } else { this.input_el.removeAttribute("value"); this.input_el.selectedIndex = -1; } } } export class Select extends InputWidget { static __name__ = "Select"; constructor(attrs) { super(attrs); } static { this.prototype.default_view = SelectView; this.define(() => { return { value: [Value, NotSelected], options: [Or(Options, OptionsGroups), []], }; }); } } //# sourceMappingURL=select.js.map