Interaction between custom Javascript and BokehJS / Python

Hi Tony,

That's great to hear, this kind of input and use case exploration could be very valuable. That said, you just reminded me that Bokeh.documents exists (I had forgotten about it), which means there is already essentially a way to do what you describe with public supported APIs. Instead of "id" there is also a "name" that users can set to any arbitrary value they like, and a method to retrieve models by name. Here is your code updated:

    from bokeh.models.widgets import Div, TextInput
    from bokeh.layouts import column
    from bokeh.io import curdoc

    def get_div(nmb):
        js = "Bokeh.documents[0].get_model_by_name('text_input').value = '{nmb}'".format(nmb = nmb)
        return(Div(text = ('<div style="cursor:pointer" onclick="{js}">Set Value {nmb}</div>'.format(js = js, nmb = nmb))))

    def update():
        div_txt.text = 'Value: ' + txt.value

    txt = TextInput(value = "", name = "text_input")
    div_txt = Div(text = 'Value: ')

    curdoc().add_root(column(get_div(1), get_div(2), txt, div_txt))
    curdoc().add_periodic_callback(update, 250)

I'd love to discuss how this could be made even easier/better. Certainly we could make some examples and docs around this kind of usage.

Thanks,

Bryan

···

On Feb 9, 2019, at 15:08, [email protected] wrote:

Bryan, Thanks. I got it.
Sure, I am open for contribution to improvements in my so called “hobby time” :slight_smile:
I think Bokeh has future and interaction with custom/3rd party JS packages, build with webpack or tsc (typescript) would be a great added value.

I think a good starting point would be to let the user to set a global DOM element “id” (like now the auto-generated one e.g. “490ad07e-7ad1-4e6c-ab28-205e3385875e”) per widget on Python level.
Than one could simply use the standard jquery setters/getters ($) to obtain interaction.
This could help building e.g. SPA that communicates with database (mongo, sql) via AJAX and displas the data.

Here is my modified code:

from bokeh.models.widgets import Div, TextInput
from bokeh.layouts import column
from bokeh.io import curdoc

def get_div(nmb):
    js = "Bokeh.documents[0]['_all_models'].text_input['value'] = '{nmb}'".format(nmb = nmb)
    return(Div(text = ('<div style="cursor:pointer" onclick="{js}">Set Value {nmb}</div>'.format(js = js, nmb = nmb))))

def update():
    div_txt.text = 'Value: ' + txt.value

txt = TextInput(value = "", id = "text_input")
div_txt = Div(text = 'Value: ')

curdoc().add_root(column(get_div(1), get_div(2), txt, div_txt))
curdoc().add_periodic_callback(update, 250)

On Saturday, February 9, 2019 at 1:53:19 AM UTC+1, Bryan Van de ven wrote:
Hi,

BokehJS is only able to notice (and hence, automatically sync to Python) if you set the property on the actual BokehJS object, i.e. with

    text_input.value = "new text" // not the DOM element, the BokehJS object

BokehJS is not able to detect pure DOM changes like the one you are making. Unfortunately, it will be trivial to get ahold of the object outside of Bokeh's CustomJS callbacks. There is a global Bokeh.index that has all of the view objects. You will just have to root around that to find the text input view you want, and then set its .model.value to update. This is not a commonly used or requested kind of interaction with bokeh, so it is not highly developed. but we would certainly be receptive to suggestions motivated by real use cases (and especially if you can help with implementing improvements).

Thanks,

Bryan

> On Feb 8, 2019, at 16:49, tony12...@gmail.com wrote:
>
> Hi all,
>
> I have a problem with passing a value from javascript to Python.
> When I click a dynamically created Div (Set value: 1, 2) it sets a value in the TextInput.
> This value is however not seen by Python.
>
> To test it I created another Div (Value: ) that continuously displays the TextInput value.
> This Div value changes only when I MANUALLY click and change the TextInput value.
> It doen’t change when I click the dynamically created Div’s that also set that TextInput.
>
> How is the sync between BokehJS and the Python done?
> I just want to pass a value to the BokehJS and eventually to Python.
> Is here any work around to make this work?
>
> Bokeh info:
> Python version : 3.5.1 (default, Feb 1 2019, 21:29:47)
> IPython version : (not installed)
> Tornado version : 4.5.3
> Bokeh version : 1.0.4
> BokehJS static path : /usr/local/lib/python3.5/site-packages/bokeh/server/static
> node.js version : v6.16.0
> npm version : 3.10.10
>
> I run the code below as follow:
> bokeh serve --show main.py
>
> The main.py is as follows:
> from bokeh.models.widgets import Div, TextInput
> from bokeh.layouts import column
> from bokeh.io import curdoc
>
> div1 = Div(text = '<div style="cursor:pointer" onclick="text_input=document.getElementById(\'text_input\');text_input.value=\'1\';">Set Value: 1</div>')
> div2 = Div(text = '<div style="cursor:pointer" onclick="text_input=document.getElementById(\'text_input\');text_input.value=\'2\';">Set Value: 2</div>')
>
> prefix = 'Value: '
> div_txt = Div(text = prefix)
>
> txt = TextInput(value = "", id = "text_input")
> layout = column(div1, div2, txt, div_txt)
>
> def update():
> div_txt.text = prefix + txt.value
>
> curdoc().add_root(layout)
> curdoc().add_periodic_callback(update, 500)
>
>
>
>
>
>
> --
> You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to bokeh+un...@continuum.io.
> To post to this group, send email to bo...@continuum.io.
> To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/2f32354a-2725-4ec4-a231-bfa284de5463%40continuum.io\.
> For more options, visit https://groups.google.com/a/continuum.io/d/optout\.

--
You received this message because you are subscribed to the Google Groups "Bokeh Discussion - Public" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/continuum.io/d/msgid/bokeh/57a24003-dd8b-418f-956c-40692cf16a66%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.