Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make a bokeh TextInput callback responsive as text is typed #8676

Closed
russellburdt opened this issue Feb 20, 2019 · 11 comments
Closed

make a bokeh TextInput callback responsive as text is typed #8676

russellburdt opened this issue Feb 20, 2019 · 11 comments

Comments

@russellburdt
Copy link
Contributor

@russellburdt russellburdt commented Feb 20, 2019

This feature is described originally in a Stack Overflow question, where it was recommended to create a GitHub issue.

Current functionality of the on_change method of a bokeh TextInput object is to run the callback after all text is typed and then some other key is pressed. I want to know if a TextInput object can be configured to run a callback as text is being typed / deleted. The following code is a minimal example. The application created by the code demonstrates the issue.

from bokeh.io import curdoc
from bokeh.layouts import widgetbox, column
from bokeh.models import TextInput, Button

button = Button(button_type='success')
ti = TextInput(title='enter text to enable button')
layout = column(
    widgetbox(ti),
    widgetbox(button))

button.disabled = True

def callback(attr, old, new):
    if ti.value != '':
        button.disabled = False
    else:
        button.disabled = True

ti.on_change('value', callback)

curdoc().add_root(layout)
@bryevdv
Copy link
Member

@bryevdv bryevdv commented Mar 5, 2019

For compatibility this would need to be configurable as a mode of operation (default off)

Loading

@jsignell
Copy link
Contributor

@jsignell jsignell commented Mar 7, 2019

It'd be nice to have the text input be more configurable generally - so that a user could specify that the event only be triggered when enter key is pressed.

Loading

@russellburdt
Copy link
Contributor Author

@russellburdt russellburdt commented Mar 7, 2019

I agree the objective is to develop a generally more configurable TextInput object for bokeh, with default behavior matching current behavior.

@bryevdv Do you think the bulk of the work to implement this feature will be in javascript or python.

Loading

@bryevdv
Copy link
Member

@bryevdv bryevdv commented Mar 7, 2019

It's all in Javascript (Typescript) The only thing on the python side is ~1 line to add the new property

Loading

@russellburdt
Copy link
Contributor Author

@russellburdt russellburdt commented Mar 7, 2019

@bryevdv I can attempt the work but may get hung up due to a lack of javascript / typescript experience. Where do I go next?

Loading

@bryevdv
Copy link
Member

@bryevdv bryevdv commented Mar 7, 2019

@russellburdt the first step is getting set up to build BokehJS locally:

https://bokeh.pydata.org/en/latest/docs/dev_guide/setup.html#devguide-setup

After that, the places to modify are:

Loading

@mcastanlaris
Copy link

@mcastanlaris mcastanlaris commented Apr 4, 2019

@russellburdt hi russell! What's the status with this feature? I can help out if you need some javascript help

Loading

@russellburdt
Copy link
Contributor Author

@russellburdt russellburdt commented Apr 5, 2019

@mcastanlaris Hi Maria. Thank you for following up. I have not yet started on any of Bryan's recommended steps. My plan is still to contribute to bokeh, starting with this feature, and I will reach out to you with any javascript issues encountered.

Loading

@russellburdt
Copy link
Contributor Author

@russellburdt russellburdt commented Apr 19, 2019

@mcastanlaris Hello and I think the scripts/dep.py module can be updated to silence a warning. When installing dependencies for conda packages, this happens
$ python scripts/deps.py build scripts/deps.py:17: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details. meta_src = yaml.load(meta_src.render(load_setup_py_data=load_setup_py_data)) certifi jinja2 nodejs>=8.8 numpy packaging pycurl python-dateutil pyyaml setuptools six tornado>=4.3 yaml

I was able to get past this warning by modifying line 17 in scripts/deps.py -
meta_src = yaml.load(meta_src.render(load_setup_py_data=load_setup_py_data), Loader=yaml.FullLoader)

Loading

@russellburdt
Copy link
Contributor Author

@russellburdt russellburdt commented Apr 28, 2019

@mcastanlaris @bryevdv Some progess has been made and I would really appreciate some javascript guidance at this point. I created the new Bool property in the TextInput Python class, as you see below. I also had to add the Bool object to the Bokeh imports in inputs.py. I validated none of that broke bokeh by testing with my original StackOverflow question. The modified TextInput class is below.

At this point I need to modify text_input.ts to access the new property and control the callback functionality accordingly, but am not sure how to get started doing that.

class TextInput(InputWidget):
    ''' Single-line input widget.

    '''

    value = String(default="", help="""
    Initial or entered text value.
    """)

    callback = Instance(Callback, help="""
    A callback to run in the browser whenever the user unfocuses the
    ``TextInput`` widget by hitting Enter or clicking outside of the text box
    area.
    """)

    focused = Bool(False, help="""
    set True to execute the callback when the widget is focused as text is
    entered or erased.  default value of False executes the callback only
    when the user unfocuses the ``TextInput`` widget.
    """)

    placeholder = String(default="", help="""
    Placeholder for empty input field
    """)

Thank you for the help!

Loading

@mcastanlaris
Copy link

@mcastanlaris mcastanlaris commented May 9, 2019

@russellburdt any updates on this? How's the javascript work going and are you blocked on anything specific I can help with?

Loading

bryevdv added a commit that referenced this issue Jul 20, 2019
* new property "wait_commit" for the event listener

Related to issue #8676
Adds a new boolean property "wait_commit" which controls the event listener: "change" if True (default) or "input" if False.
* wait_commit=True keeps the current behaviour (the callback is triggered once the user unfocuses the text area)
* wait_commit=False triggers the callback as text is being typed

* new property "wait_commit" for the event listener

Related to issue #8676
Adds a new boolean property "wait_commit" which controls the event listener: "change" if True (default) or "input" if False.
* wait_commit=True keeps the current behaviour (the callback is triggered once the user unfocuses the text area)
* wait_commit=False triggers the callback as text is being typed

* fixed missing import

* fixed HTMLInputElement error on nonexistent property

* Code quality: fixed trailing whitespace

* new property value_input that triggers callback on "input" event

* remove unused import

* reverted to unique function change_input

* Update text_input.ts

* reverted to using 2 functions for change_input
@bryevdv bryevdv removed this from the short-term milestone Jul 20, 2019
@bryevdv bryevdv added this to the 1.3 milestone Jul 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

4 participants