Data table editing - change when user changes input value

Hi,

I have a data table with x and y values and a third column which is the sum of x and y. Is it possible to add a js_on_change when the user changes the x value for a specific row so that the total value is updated. I can see in the plot the value changes, but is there a way to add a javascript that recalculates the sum and updates it in the data table?
Sample code below:)

from random import randint

import numpy as np
from bokeh.io import output_file, show
from bokeh.layouts import widgetbox, gridplot, row, column
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import DataTable, DateFormatter, TableColumn
from bokeh.plotting import figure

output_file("data_table.html")
x=[randint(0, 100) for i in range(10)]
y=[randint(0, 100) for i in range(10)]
total = np.sum([x, y], axis = 0)

source = ColumnDataSource(dict(x=x, y=y, total = total))

columns = [
    TableColumn(field="x", title="x"),
    TableColumn(field="y", title="y"),
    TableColumn(field="total", title="total"),
]

TOOLS = "pan,wheel_zoom,box_select,reset"
fig1 = figure(plot_width=600, plot_height=600, tools=TOOLS)
fig1.circle('x', 'y', source=source,size=10,selection_color="red", hover_color="green")

data_table= DataTable(source=source, columns=columns, width=600, height=600, editable = True)

p = gridplot([[fig1],[data_table]],
                        toolbar_location = "above")
tot =row(p)
show(column(tot))

Check out this answer: python - Callback to datatable when user changes a content of cell - Stack Overflow

1 Like

Thanks for the help! Thought I would share what I did to get it working in case someone else wants to do the same.
Let me know if you see any improvements on the javascript part :stuck_out_tongue:

from bokeh.io import show
from bokeh.models import DataTable, TableColumn, ColumnDataSource, CustomJS
from random import randint

import numpy as np
from bokeh.io import output_file, show
from bokeh.layouts import widgetbox, gridplot, row, column
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import DataTable, DateFormatter, TableColumn
from bokeh.plotting import figure

output_file("data_table.html")
x=[randint(0, 100) for i in range(10)]
y=[randint(0, 100) for i in range(10)]
total = np.sum([x, y], axis = 0)

source = ColumnDataSource(dict(x=x, y=y, total = total))

columns = [
    TableColumn(field="x", title="x"),
    TableColumn(field="y", title="y"),
    TableColumn(field="total", title="total"),
]

TOOLS = "pan,wheel_zoom,box_select,reset"
fig1 = figure(plot_width=600, plot_height=600, tools=TOOLS)
fig1.circle('x', 'y', source=source,size=10,selection_color="red", hover_color="green")

data_table= DataTable(source=source, columns=columns, width=600, height=600, editable = True)

source.js_on_change('patching', CustomJS(code="""
var x = cb_obj.attributes.data['x']
var y = cb_obj.attributes.data['y']

var total = y.map(function (num, idx) {
  return parseInt(num) + parseInt(x[idx]);
});

cb_obj.attributes.data['total'] = total
"""
))

p = gridplot([[fig1],[data_table]],
                        toolbar_location = "above")
tot =row(p)
show(column(tot))
2 Likes