How to access values from html.Select?

Hi,
I just stumbled upon Dash and want to thank everyone involved, this seems like a very helpful project for someone familiar with Python and data analysis but wary of html, not to mention javascript!
I would like to populate a list with values from a database and then select (multiple) values of that list to generate graphs.
Looking through the help of html.Select, I could not figure out how to access the selected values. The only property containing data that dash seems to provide access to is the ā€˜childrenā€™, but this has no info on whether a value is selected or not. I tried accessing various properties of both the html.Select as well as the parent html.Form object in all permutations I could think of.
It would be really great if someone can point me in the right direction. I understand that the html components probably donā€™t have as high a priority in documentation and features compared to the core components. Sorry if this is a trivial issue, but I donā€™t know whether to look for a solution in Dash or html. Iā€™m running the dash app in a Flask server instance (to later implement several dash apps), so one option would probably be to generate the form in a flask template, but I was hoping to do it from within Dash.
Below is a snippet of how I generate the select list and want to use it in a callback.

app.layout = html.Div(
children=[
html.H1(children='title'),
dcc.Graph(id='plot', figure=fig),
html.Form(
html.Select(html.Option([i for i in wafers.WaferID.values[:10]]), size='10', multiple='multiple',name='wafer_list', id='wafer_list')
        , name='wafer_form', id='wafer_form', method='POST')
])

@app.callback(
    Output(component_id='plot', component_property='figure'),
    [Input(component_id='wafer_form', component_property='children')],
    events=[Event('wafer_list','click')],
    state=[State('wafer_list','children')])
def update_plot(WaferID, state): 
    # use selected values from callback of 'wafer_list' or 'wafer_form' to update Graph

dash_html_components arenā€™t interactive by default, so things like html.Input or html.Select wonā€™t work (right now). In their place, interactive forms in dash_core_components are provided: dcc.Input and dcc.Dropdown.

Instead of html.Select, can you use dcc.Dropdown?

Thank you for your feedback. The problem with the dropdown is that the list will contain several hundred items and thereā€™s up to maybe a dozen, often non-consecutive items to select. With a select box of the right size and vertical scrollbar that is way easier than with a dropdown.
I think Iā€™ll create the with flask for now. If I had more experience in html and js Iā€™d be happy to help with the html_components, because I really like the concept of dash.

In this case, it sounds like the built-in search bar of the dcc.Dropdown element would come in handy. Hereā€™s a dropdown with 1000 items and multi=True:

If the height of the option list was customizable (instead of showing 6 options by default you could show 100 options or enough options to fit the size of the page), would that make this component useful in your use case? Are there any other customizations that you need?

1 Like

Damn, I did not think of the filter option! This will actually work - typically weā€™d know the first few characters of the ID string, this will reduce it to a fairly small dropdown list.
The only advantage of the select options list would be that itā€™s easier to select slices, where the dropdown will reset the filter string in the search bar or the list of items in the dropdown with the first click on one of the items (i.e. canā€™t do a click and then shift+click for slice select). But I think this will still be a good solution.
Thank you for your help!

1 Like

I just spent some time trying to figure out how html.Select works (without JS or other stuff) to try to answer this question. Couldnā€™t quite figure it out. Anybody familiar with this? Do you need to put it in a form?

Iā€™m in the same boat. Tried numerous things but could not figure it out. The only I can get back from a select list is for each option how many times it has been clicked and when the last click was. I have been unable to figure out how to find out which items are actually selected though. I also opened a new topic on this yesterday here: List with easy multi-select
No reply as of yet.

Lol - I meant to reply on your thread with the above message.

2 Likes

I too was looking for a way to access the ā€œvalueā€ property of an html.Select element and found that it was completely inaccessible in Plotly. Not even custom JavaScript could get to it; I suspect thatā€™s because my custom JS file was getting executed before the DOM was available. I wanted to use html.Select because dcc.Dropdown does not work with screen readers, which poses an accessibility issue.

While looking for alternatives, I eventually stumbled on the Dash Bootstrap Component dbc.Select, which provided exactly what I needed. It creates a simple html Select element with Option child elements, and it has a ā€œvalueā€ property which you can register in a callback. For example, the following Python code:

dbc.Select(options=[
    {'label': 'eeney', 'value': 'eeney'},
    {'label': 'meeney', 'value': 'meeney'},
    {'label': 'miney', 'value': 'miney'},
    {'label': 'mo', 'value': 'mo'},
], id='test-dropdown')

Renders as the following html:

<select placeholder="" class="form-select" id="test-dropdown">
	<option value="" disabled="" hidden=""></option>
	<option value="eeney">eeney</option>
	<option value="meeney">meeney</option>
	<option value="miney">miney</option>
	<option value="mo">mo</option>
</select>

And you can listen for changes to ā€œvalueā€:

@app.callback(
    Input('test-dropdown', 'value')
)

It took me about two days to solve this. Finally even trying to access all the properties under html.Option and html.Select I couldnā€™t make it work. Then I decided to use a diffent approach, basically is to use a Ag.Grid then make it look like a multiple select.

At first by accessing the ctx I managed to get the multiple values however I couldnt get the ones selected in the middle of the ones I clicked.

                                       dag.AgGrid(
                                                    id="transactions-grid",
                                                    rowData=reg(engine),
                                                    columnDefs=columnDefs,
                                                    defaultColDef={"minWidth": 160},
                                                    dashGridOptions={"rowSelection": "multiple",
                                                                         "rowHeight": 22,
                                                                 'groupHeaderHeight': 0,
                                                                      'headerHeight': 0},
                                                    getRowId="params.data.fecha",
                                                    style = {"height":100,'width':185}
                                                ),
1 Like