@bokeh/bokehjs
Version:
Interactive, novel data visualization
106 lines • 3.39 kB
JavaScript
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