UNPKG

@bokeh/bokehjs

Version:

Interactive, novel data visualization

358 lines 10.3 kB
import { input, textarea, select, option } from "../../../core/dom"; import { isInteger, isString } from "../../../core/util/types"; import { DOMComponentView } from "../../../core/dom_view"; import { Model } from "../../../model"; import { DTINDEX_NAME } from "./definitions"; import * as tables from "../../../styles/widgets/tables.css"; export class CellEditorView extends DOMComponentView { static __name__ = "CellEditorView"; defaultValue; get emptyValue() { return null; } inputEl; args; constructor(options) { const { model, parent } = options.column; super({ model, parent, ...options }); this.args = options; this.initialize(); // XXX: no build_views() this.render(); // XXX: this isn't governed by layout } initialize() { super.initialize(); this.inputEl = this._createInput(); this.defaultValue = null; } async lazy_initialize() { throw new Error("unsupported"); } css_classes() { return super.css_classes().concat(tables.cell_editor); } render() { this.args.container.append(this.el); this.shadow_el.appendChild(this.inputEl); this.renderEditor(); this.disableNavigation(); } renderEditor() { } disableNavigation() { // XXX: without cast `event` is of non-specific type `Event` this.inputEl.addEventListener("keydown", (event) => { switch (event.key) { case "ArrowLeft": case "ArrowRight": case "ArrowUp": case "ArrowDown": case "PageUp": case "PageDown": { event.stopImmediatePropagation(); break; } } }); } destroy() { this.remove(); } focus() { this.inputEl.focus(); } show() { } hide() { } position() { } getValue() { return this.inputEl.value; } setValue(val) { this.inputEl.value = val; } serializeValue() { return this.getValue(); } isValueChanged() { return !(this.getValue() == "" && this.defaultValue == null) && this.getValue() !== this.defaultValue; } applyValue(item, state) { const grid_data = this.args.grid.getData(); const offset = grid_data.index.indexOf(item[DTINDEX_NAME]); grid_data.setField(offset, this.args.column.field, state); } loadValue(item) { const value = item[this.args.column.field]; this.defaultValue = value != null ? value : this.emptyValue; this.setValue(this.defaultValue); } validateValue(value) { if (this.args.column.validator) { const result = this.args.column.validator(value); if (!result.valid) { return result; } } return { valid: true, msg: null }; } validate() { return this.validateValue(this.getValue()); } } export class CellEditor extends Model { static __name__ = "CellEditor"; } export class StringEditorView extends CellEditorView { static __name__ = "StringEditorView"; get emptyValue() { return ""; } _createInput() { return input({ type: "text" }); } renderEditor() { //completions = @model.completions //if completions.length != 0 // @inputEl.classList.add("bk-cell-editor-completion") // $(@inputEl).autocomplete({source: completions}) // $(@inputEl).autocomplete("widget") this.inputEl.focus(); this.inputEl.select(); } loadValue(item) { super.loadValue(item); this.inputEl.defaultValue = this.defaultValue; this.inputEl.select(); } } export class StringEditor extends CellEditor { static __name__ = "StringEditor"; static { this.prototype.default_view = StringEditorView; this.define(({ Str, List }) => ({ completions: [List(Str), []], })); } } export class TextEditorView extends CellEditorView { static __name__ = "TextEditorView"; _createInput() { return textarea(); } renderEditor() { this.inputEl.focus(); this.inputEl.select(); } } export class TextEditor extends CellEditor { static __name__ = "TextEditor"; static { this.prototype.default_view = TextEditorView; } } export class SelectEditorView extends CellEditorView { static __name__ = "SelectEditorView"; _createInput() { return select(); } renderEditor() { for (const opt of this.model.options) { this.inputEl.appendChild(option({ value: opt }, opt)); } this.focus(); } } export class SelectEditor extends CellEditor { static __name__ = "SelectEditor"; static { this.prototype.default_view = SelectEditorView; this.define(({ Str, List }) => ({ options: [List(Str), []], })); } } export class PercentEditorView extends CellEditorView { static __name__ = "PercentEditorView"; _createInput() { return input({ type: "text" }); } } export class PercentEditor extends CellEditor { static __name__ = "PercentEditor"; static { this.prototype.default_view = PercentEditorView; } } export class CheckboxEditorView extends CellEditorView { static __name__ = "CheckboxEditorView"; _createInput() { return input({ type: "checkbox" }); } renderEditor() { this.focus(); } loadValue(item) { this.defaultValue = !!item[this.args.column.field]; this.inputEl.checked = this.defaultValue; } serializeValue() { return this.inputEl.checked; } } export class CheckboxEditor extends CellEditor { static __name__ = "CheckboxEditor"; static { this.prototype.default_view = CheckboxEditorView; } } export class IntEditorView extends CellEditorView { static __name__ = "IntEditorView"; _createInput() { return input({ type: "text" }); } renderEditor() { //$(@inputEl).spinner({step: @model.step}) this.inputEl.focus(); this.inputEl.select(); } remove() { //$(@inputEl).spinner("destroy") super.remove(); } serializeValue() { const value = parseInt(this.getValue(), 10); return isNaN(value) ? 0 : value; } loadValue(item) { super.loadValue(item); this.inputEl.defaultValue = this.defaultValue; this.inputEl.select(); } validateValue(value) { if (isString(value)) { value = Number(value); } if (isInteger(value)) { return super.validateValue(value); } else { return { valid: false, msg: "Please enter a valid integer" }; } } } export class IntEditor extends CellEditor { static __name__ = "IntEditor"; static { this.prototype.default_view = IntEditorView; this.define(({ Int }) => ({ step: [Int, 1], })); } } export class NumberEditorView extends CellEditorView { static __name__ = "NumberEditorView"; _createInput() { return input({ type: "text" }); } renderEditor() { //$(@inputEl).spinner({step: @model.step}) this.inputEl.focus(); this.inputEl.select(); } remove() { //$(@inputEl).spinner("destroy") super.remove(); } serializeValue() { const value = parseFloat(this.getValue()); return isNaN(value) ? 0.0 : value; } loadValue(item) { super.loadValue(item); this.inputEl.defaultValue = this.defaultValue; this.inputEl.select(); } validateValue(value) { if (isNaN(value)) { return { valid: false, msg: "Please enter a valid number" }; } else { return super.validateValue(value); } } } export class NumberEditor extends CellEditor { static __name__ = "NumberEditor"; static { this.prototype.default_view = NumberEditorView; this.define(({ Float }) => ({ step: [Float, 0.01], })); } } export class TimeEditorView extends CellEditorView { static __name__ = "TimeEditorView"; _createInput() { return input({ type: "text" }); } } export class TimeEditor extends CellEditor { static __name__ = "TimeEditor"; static { this.prototype.default_view = TimeEditorView; } } export class DateEditorView extends CellEditorView { static __name__ = "DateEditorView"; _createInput() { return input({ type: "text" }); } get emptyValue() { return new Date(); } renderEditor() { //this.calendarOpen = false //@$datepicker = $(@inputEl).datepicker({ // showOn: "button" // buttonImageOnly: true // beforeShow: () => @calendarOpen = true // onClose: () => @calendarOpen = false //}) //@$datepicker.siblings(".ui-datepicker-trigger").css("vertical-align": "middle") //@$datepicker.width(@$datepicker.width() - (14 + 2*4 + 4)) # img width + margins + edge distance this.inputEl.focus(); this.inputEl.select(); } destroy() { //$.datepicker.dpDiv.stop(true, true) //@$datepicker.datepicker("hide") //@$datepicker.datepicker("destroy") super.destroy(); } show() { //if @calendarOpen // $.datepicker.dpDiv.stop(true, true).show() super.show(); } hide() { //if @calendarOpen // $.datepicker.dpDiv.stop(true, true).hide() super.hide(); } position( /*_position*/) { //if @calendarOpen // $.datepicker.dpDiv.css(top: position.top + 30, left: position.left) return super.position(); } getValue() { //return @$datepicker.datepicker("getDate").getTime() } setValue(_val) { //@$datepicker.datepicker("setDate", new Date(val)) } } export class DateEditor extends CellEditor { static __name__ = "DateEditor"; static { this.prototype.default_view = DateEditorView; } } //# sourceMappingURL=cell_editors.js.map