gradio-app / gradio

Build and share delightful machine learning apps, all in Python. 🌟 Star to support our work!
http://www.gradio.app
Apache License 2.0
33.42k stars 2.53k forks source link

`.change` or `.input` event isn't triggered while typing in `gr.Dropdown` when `filterable=True` #7388

Closed apolinario closed 8 months ago

apolinario commented 8 months ago

Describe the bug

Currently, .change or .input events are only triggered in gr.Dropdown if an option is selected and not while being typed (when filterable=True allows typing) as it is for the gr.Textbox().

As the .select event already fulfils the purpose of only triggering an event if a valid option is selected - I think .change/.input become a bit redundant for such use-case. This is the reason why this is filled as a bug and not a feature request (imo as the .select event already behaves for option selection, it is a bug that .change/.input isn't triggered while the user is typing with filterable=True).

Addressing this bug would allow for cool new use-cases such as changing the options in the dropdown component in real time based on what the user is typing (e.g.: quick search). Internal thread with more context

Have you searched existing issues? 🔎

Reproduction

import gradio as gr
import requests
import time

def search_huggingface_datasets(query):
    if not query:  # If the query is empty, return an empty list
        return []
    url = f"https://huggingface.co/api/quicksearch?q={query}&type=dataset&limit=20"
    print(url)
    response = requests.get(url)
    if response.status_code == 200:
        data = response.json()
        print(data)
        dataset_names = [d['id'] for d in data['datasets']]
        return dataset_names
    else:
        return ["Error fetching datasets"]

def update_dropdown(query):
    datasets = search_huggingface_datasets(query)
    return gr.update(choices=datasets, visible=True)

with gr.Blocks() as demo:
    with gr.Row():
        dataset_dropdown = gr.Dropdown(label="Datasets", choices=[""], elem_id="dataset_list", interactive=True, filterable=True, allow_custom_value=True)
    dataset_dropdown.change(update_dropdown, inputs=dataset_dropdown, outputs=dataset_dropdown, queue=False, show_progress="hidden")
demo.launch(debug=True)

Colab: https://colab.research.google.com/drive/1NynI5ZtQs3F8RAoCq3GhUYMU19ji3iEB?usp=sharing Space: https://huggingface.co/spaces/multimodalart/gradio-dropdown-autocomplete

Video

https://github.com/gradio-app/gradio/assets/788417/c5d6985b-1433-40e0-b983-be4ef8b5f2f7

Logs

No response

System Info

gradio==4.18.0

Severity

I can work around it

abidlabs commented 8 months ago

Very cool @apolinario! We could definitely add a new event .type() that gets triggered at every keystroke. I think a .change() event is not suitable here because that is only triggered when the value of a component changes, which is not the case if a user just types a letter into the Dropdown component

apolinario commented 8 months ago

I see! Maybe when allow_custom_value=True then the value of the component may be considered changing in real time? (Similar to how the gr.Textbox() triggers per keystroke and not only when unfocused).

But I agree a .type() event would be great!