Multiselect jupyter notebook update value?

Hi,

Not sure if this is possible in jupyter notebook. But I have a list of names (over 700 names) which I would like to user to be able to select based on the MultiSelect tool. The tool is nice because it autofills or finds names close to what is typed. Wanted to add this to a notebook. I assume its not possible to update a variable as done below? Source is kinda disconnected to what is happening into custom js field? Does anyone have an idea how I can have the user find the relevant name easily?

There’s an AutocompleteInput widget: inputs — Bokeh 2.4.3 Documentation
, I think that’s what you’re after.

1 Like

Hi, I still dont know how I can use the value inputted in the widget?

here an example:

from bokeh.plotting import show, output_notebook, output_file
from bokeh.models.widgets import AutocompleteInput

output_notebook()

input_widget = AutocompleteInput(completions=['pok', 'wer', 'foo', 'bar', 'baz'], title='test')
show(input_widget)

Now if the user writes “foo”. I would like the name to be used elsewhere in the code. Is it stored somewhere?

Yes! Ironically enough, the value selected in the widget is stored in its ‘value’ property:

from bokeh.plotting import show, output_notebook, output_file
from bokeh.models import AutocompleteInput,CustomJS


input_widget = AutocompleteInput(completions=['pok', 'wer', 'foo', 'bar', 'baz'], title='test')

cb = CustomJS(args=dict(inp=input_widget)
              ,code='''
              console.log('this is what the user selected: '+inp.value)
              ''')
input_widget.js_on_change('value',cb)

show(input_widget)

So you can write callbacks that use that value to do stuff.

Hi,

I could be asking something that might not be possible. But I saw some examples on embedding in jupyter notebook.
What I am trying to do is use the value selected in another cell :stuck_out_tongue: (f.ex in the last cell below, the input_widget.value is empty.

1 Like

Thanks for this question, I just learned something.

So my current understanding is that output_notebook() will embed standalone html/JS and no longer “talk” to the python variables (so in your case input_widget, as an instance of a python class, its value property never gets altered, but its javascript equivalent does)… i.e. there’s no interaction between the python in your notebook and the html embedded in it.

So that got me thinking that there is probably a way to embed bokeh server within a jupyter notebook, which would then actually alter the state of the python stuff.

This example bokeh/notebook_embed.ipynb at branch-3.0 · bokeh/bokeh · GitHub and this doc: Using with Jupyter — Bokeh 2.2.3 Documentation helped me figure this out.

from bokeh.plotting import show, output_notebook, output_file
from bokeh.models import AutocompleteInput,CustomJS
from ipywidgets import interact
output_notebook()

def bkapp(doc):
    global input_widget
    input_widget = AutocompleteInput(completions=['pok', 'wer', 'foo', 'bar', 'baz'], title='test')     
    doc.add_root(input_widget)

show(bkapp, notebook_url="http://localhost:8890") #need to update notebook_url arg with your localhost url (mine was 8890)

Now what’s pretty hokey about this is the use of a global variable to hold the input_widget and get it outside the bkapp function. Wondering if there’s a cleaner way… but anyway this actually does work:

bkserve

1 Like

That’s an interesting use of global to make that happen. I am not sure how I feel about it. In a “normal” notebook app, you would only use the value in widget callbacks that were set up inside the app function.

FWIW we went in the direction of requiring notebook apps to be “encapsulated” inside a function is because allowing portions of the app to be spread across multiple cells that can be re-executed and executed out of order is unreasonable — in the absolutely literal sense of “this is nearly impossible to reason about effectively”. E.g. in such a case it would be trivial to re-execute a cell and end up with a reference to a widget object that is completely divorced from a widget that is actually displayed in another cell, without realizing it. Requiring everything to be bundled together in a single “app function” seemed like the least-worst option to avoid endless confusion.

I guess there has been some work done with jupyter and ipywidgets integration that might lift some of this restriction but I honestly don’t know much about that work.

allowing portions of the app to be spread across multiple cells that can be re-executed and executed out of order is unreasonable

Absolutely. This is a massive danger/pitfall of jupyter notebooks in general and this just makes it even more inevitable. See the “lecture” slides here: I don't like notebooks.: Jupyter Notebook conference & training: JupyterCon for solid entertainment .

@Zana Personally I’d file this under “just because you can doesn’t mean you should.”

Yes, I agree. I will most likely write the code in one function and use the parameter in one cell. But this is very useful for testing. Thanks again:)