Run arbitrary JavaScript code anytime

Hi everyone,

I would like to be able to run arbitrary JavaScript code at any point during my application runtime. The way I know, we can only run JavaScript Code that is attached to an existing widget.

Specifically, I want to display an “alert()” browser message to the user anytime I want, for example before the rest of the UI of my Bokeh application is created.

My current solution is to create a TextInput widget, add it to curdoc(), trigger its “js_on_change()” and then remove it.

def run_js_code(js_code):
ti_code = TextInput(value=’’)

ti_code.js_on_change('value', CustomJS(code=js_code))
curdoc().add_root(ti_code)
ti_code.value = ' '
curdoc().remove_root(ti_code)

message = ‘Hello World!’
js_code=""“alert(’”""+message+"""’)"""
run_js_code(js_code)

``

It works, but the downside is that an empty TextInput Box shows up somewhere on the html page while the JavaScript code runs.

Is there a more elegant solution?

I think what I am looking for is an equivalent to “add_next_tick_callback()” that works with a CustomJS object, something like “add_next_tick_js_callback()”.

Regards

Hi Joris,

I did not test it, but you should be able to create a ColumnDataSource with a “code” field and add a JS callback to it that executes everything in the “code” column whenever the data is changed.

The issue is this approach is that you can’t add a data source to the document itself, without any model that can be rendered.

More details and workarounds can be found in this mailing list, also here Add a test for `Document.add_root(not_a_component)` · Issue #3117 · bokeh/bokeh · GitHub and by following the links on that page.

Regards,

Eugene

···

On Wednesday, January 3, 2018 at 5:47:05 PM UTC+7, Joris Nettelstroth wrote:

Hi everyone,

I would like to be able to run arbitrary JavaScript code at any point during my application runtime. The way I know, we can only run JavaScript Code that is attached to an existing widget.

Specifically, I want to display an “alert()” browser message to the user anytime I want, for example before the rest of the UI of my Bokeh application is created.

My current solution is to create a TextInput widget, add it to curdoc(), trigger its “js_on_change()” and then remove it.

def run_js_code(js_code):
ti_code = TextInput(value=‘’)

ti_code.js_on_change('value', CustomJS(code=js_code))
curdoc().add_root(ti_code)
ti_code.value = ' '
curdoc().remove_root(ti_code)

message = ‘Hello World!’
js_code=“”“alert('”“”+message+“”“')”“”
run_js_code(js_code)

``

It works, but the downside is that an empty TextInput Box shows up somewhere on the html page while the JavaScript code runs.

Is there a more elegant solution?

I think what I am looking for is an equivalent to “add_next_tick_callback()” that works with a CustomJS object, something like “add_next_tick_js_callback()”.

Regards

Hi Eugene,

thanks for your answer.

This is just a check, and it works (prints the js_code to the console)

def run_js_code(js_code):

source = ColumnDataSource({'code': [0]})
source.on_change('data', print_hello)
source.data['code'] = [js_code]

def print_hello(attr, old, new):
print(new[‘code’][0])

``

But this does not work. Simply nothing happens (that I can see). And I have no idea if that would actually execute the code stored in the column…

def run_js_code(js_code):

source = ColumnDataSource({'code': [0]})
source.js_on_change('data', CustomJS(code="""cd_obj.data['code'][0]"""))
source.data['code'] = [js_code]

``

Also this check does not give any reaction (no pop-up is shown). I can’t get any JS callback to trigger.

def run_js_code(js_code):

source = ColumnDataSource({'code': [0]})
source.js_on_change('data', CustomJS(code="""alert('hello')"""))
source.data['code'] = [js_code]

``


Do the latter two examples not work, because the source would have to be added to a model? Searching the mailing list did not really help this time.

If it is too complicated, I can live with my current solution.

By the way (maybe stupid question): Is there a way to look for errors on the JavaScript side? Can I make my browser show those errors?

In Firefox I found the JavaScript-Environment (Shift+F4) which is nice to test code snippets.

Regards

···

Am Mittwoch, 3. Januar 2018 11:54:11 UTC+1 schrieb Eugene Pakhomov:

Hi Joris,

I did not test it, but you should be able to create a ColumnDataSource with a “code” field and add a JS callback to it that executes everything in the “code” column whenever the data is changed.

The issue is this approach is that you can’t add a data source to the document itself, without any model that can be rendered.

More details and workarounds can be found in this mailing list, also here https://github.com/bokeh/bokeh/issues/3117 and by following the links on that page.

Regards,

Eugene

On Wednesday, January 3, 2018 at 5:47:05 PM UTC+7, Joris Nettelstroth wrote:

Hi everyone,

I would like to be able to run arbitrary JavaScript code at any point during my application runtime. The way I know, we can only run JavaScript Code that is attached to an existing widget.

Specifically, I want to display an “alert()” browser message to the user anytime I want, for example before the rest of the UI of my Bokeh application is created.

My current solution is to create a TextInput widget, add it to curdoc(), trigger its “js_on_change()” and then remove it.

def run_js_code(js_code):
ti_code = TextInput(value=‘’)

ti_code.js_on_change('value', CustomJS(code=js_code))
curdoc().add_root(ti_code)
ti_code.value = ' '
curdoc().remove_root(ti_code)

message = ‘Hello World!’
js_code=“”“alert('”“”+message+“”“')”“”
run_js_code(js_code)

``

It works, but the downside is that an empty TextInput Box shows up somewhere on the html page while the JavaScript code runs.

Is there a more elegant solution?

I think what I am looking for is an equivalent to “add_next_tick_callback()” that works with a CustomJS object, something like “add_next_tick_js_callback()”.

Regards

FYI There is an open issue for supporting pure "function calls" across Bokeh/BokehJS boundary that you can follow or chime in on:

  Events with feedback / Simple RPC · Issue #5983 · bokeh/bokeh · GitHub

Think it would be a go feature, but there are alot of competing priorities at the moment.

THanks,

Bryan

···

On Jan 3, 2018, at 08:52, Joris Nettelstroth <[email protected]> wrote:

Hi Eugene,

thanks for your answer.

This is just a check, and it works (prints the js_code to the console)
def run_js_code(js_code):
    source = ColumnDataSource({'code': [0]})
    source.on_change('data', print_hello)
    source.data['code'] = [js_code]

def print_hello(attr, old, new):
    print(new['code'][0])

But this does not work. Simply nothing happens (that I can see). And I have no idea if that would actually execute the code stored in the column...
def run_js_code(js_code):
    source = ColumnDataSource({'code': [0]})
    source.js_on_change('data', CustomJS(code="""cd_obj.data['code'][0]"""))
    source.data['code'] = [js_code]

Also this check does not give any reaction (no pop-up is shown). I can't get any JS callback to trigger.
def run_js_code(js_code):
    source = ColumnDataSource({'code': [0]})
    source.js_on_change('data', CustomJS(code="""alert('hello')"""))
    source.data['code'] = [js_code]

Do the latter two examples not work, because the source would have to be added to a model? Searching the mailing list did not really help this time.
If it is too complicated, I can live with my current solution.

By the way (maybe stupid question): Is there a way to look for errors on the JavaScript side? Can I make my browser show those errors?
In Firefox I found the JavaScript-Environment (Shift+F4) which is nice to test code snippets.

Regards

Am Mittwoch, 3. Januar 2018 11:54:11 UTC+1 schrieb Eugene Pakhomov:
Hi Joris,

I did not test it, but you should be able to create a ColumnDataSource with a "code" field and add a JS callback to it that executes everything in the "code" column whenever the data is changed.

The issue is this approach is that you can't add a data source to the document itself, without any model that can be rendered.
More details and workarounds can be found in this mailing list, also here Add a test for `Document.add_root(not_a_component)` · Issue #3117 · bokeh/bokeh · GitHub and by following the links on that page.

Regards,
Eugene

On Wednesday, January 3, 2018 at 5:47:05 PM UTC+7, Joris Nettelstroth wrote:
Hi everyone,

I would like to be able to run arbitrary JavaScript code at any point during my application runtime. The way I know, we can only run JavaScript Code that is attached to an existing widget.
Specifically, I want to display an “alert()” browser message to the user anytime I want, for example before the rest of the UI of my Bokeh application is created.

My current solution is to create a TextInput widget, add it to curdoc(), trigger its “js_on_change()” and then remove it.

def run_js_code(js_code):
    ti_code = TextInput(value='')
    ti_code.js_on_change('value', CustomJS(code=js_code))
    curdoc().add_root(ti_code)
    ti_code.value = ' '
    curdoc().remove_root(ti_code)

message = 'Hello World!'
js_code="""alert('"""+message+"""')"""
run_js_code(js_code)

It works, but the downside is that an empty TextInput Box shows up somewhere on the html page while the JavaScript code runs.

Is there a more elegant solution?
I think what I am looking for is an equivalent to “add_next_tick_callback()” that works with a CustomJS object, something like “add_next_tick_js_callback()”.

Regards

--
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/e98eabdf-942f-4590-a4ff-791d6be35f56%40continuum.io\.
For more options, visit https://groups.google.com/a/continuum.io/d/optout\.