Reputation: 449
I'm trying to create a bokeh server (running with Python -m bokeh serve my_pythonfile.py) where I let the user modify some data that I want to use in a CustomJS function. I tried to make a simple example of my class here:
def __init__(self):
self.data = 0
self.click_me = self._get_click_button()
self.save_data = self._get_save_data()
def _get_click_button(self) -> Button:
click_me = Button(label='Add data')
click_me.on_click(self.add_data)
return click_me
def self.add_data(self):
self.data += 1
def _get_save_data(self) -> Button:
save = Button(label='Save data')
callback = CustomJS(args={'data': self.return_data()}, code="""console.log(data);""")
save.js_on_click(callback)
return save
def return_data(self) -> int:
return self.data
When I press on the Save data
button I always get 0 in the console, I understand why but I don't know how to get the actual number of self.data
, any ideas/tips?
The actual things that I want to do is to let the user download some data (a json file) and one solution that came to mind was use the html5 keyword download
. In another case I wanted to use the alert
keyword to let the user know that he have entered some bad data.
Upvotes: 0
Views: 406
Reputation: 43083
A native int
value is not synced between the Bokeh server and the client.
args={'data': self.return_data()}
is essentially args={'data': 0}
.
To sync an object between the server and client, subclass Model
and use it.
from bokeh.core.properties import Int
from bokeh.models import Model
from bokeh.util.compiler import TypeScript
class MyModel(Model):
__implementation__ = TypeScript("""
import { Model } from "model";
export class MyModel extends Model {
constructor(attrs: any) {
super(attrs);
}
static init_MyModel() {
this.define(({ Int }) => ({
data: [Int, 0] as any,
}));
}
}
""")
data = Int
Usage:
def __init__(self):
self.model = MyModel(data=0) # Modified
self.click_me = self._get_click_button()
self.save_data = self._get_save_data()
def _get_click_button(self) -> Button:
click_me = Button(label='Add data')
click_me.on_click(self.add_data)
return click_me
def add_data(self):
self.model.data += 1 # Modified
def _get_save_data(self) -> Button:
save = Button(label='Save data')
callback = CustomJS(args={'model': self.model}, code="""console.log(model.data);""") # Modified
save.js_on_click(callback)
return save
# def return_data(self) -> int: # Removed
# return self.data # Removed
Upvotes: 1