Hi, I wanted to try using a ColumnDataSource to be able to discriminate when a js_on_change callback is triggered by manually changing the value of the object itself, or when it is triggered by another callback changing the object value. Here is the example code:
from bokeh.plotting import figure
from bokeh.models import NumericInput, ColumnDataSource, CustomJS, Row, HoverTool
from bokeh.resources import CDN
from bokeh.embed import file_html
manual_source = ColumnDataSource(data={"flag": [1]})
scatter_source = ColumnDataSource(data={"x": list(range(5)), "y": list(range(5))})
inp = NumericInput(value=None)
inp.js_on_change(
"value",
CustomJS(
args={"manual_source": manual_source},
code="""
if (manual_source.data["flag"][0]==1) {
console.log("Triggered by manual input to inp");
} else {
console.log("Triggered by another callback");
manual_source.data["flag"][0] = 1;
manual_source.change.emit();
}
console.log("inp: " + manual_source.data["flag"][0]);
""",
),
)
fig = figure(tools=["hover"])
hover = fig.select_one(HoverTool)
hover.callback = CustomJS(
args={
"inp": inp,
"manual_source": manual_source,
},
code="""
const selected = cb_data["index"].indices;
if (selected.length>0) {
manual_source.data["flag"][0] = 0;
inp.value = selected[selected.length-1];
console.log("hover: " + manual_source.data["flag"][0]);
}
""",
)
fig.scatter("x", "y", source=scatter_source)
layout = Row(fig, inp)
with open("test.html", "w") as out:
out.write(file_html(layout, CDN, "test", suppress_callback_warning=True))
It kind of works, except that after a hover, the value of the manual_source is 0 instead of the 1 I was expecting, despite it being 1 at the end of the inp callback.
I also attach a screen capture of the issue with the console messages, on hover, the inp log shows 1 but the hover log (which should happen “after” and i think that may be my misunderstanding of the callbacks inner working) shows 0.
So after the hover, I have to manually change the input value twice before manual_source.data[‘flag’][0] == 1.
Anything I can do to have the value as 1 at the console.log("hover
line ?