5

Is there a dash component like this:

enter image description here

Basically a text input, but with a list of removable items, added by hitting enter.

I know a dropdown can be made to work like this, but I don't have a specified list of options beforehand.

Barmar
  • 741,623
  • 53
  • 500
  • 612

1 Answers1

3

If you're open to dash components that are not standard, I would go for Tag input from Tauffer consulting. And if you would like to use approaches that ship with Dash, you can put together a few components to mimic a very similar functionality. Both approaches are described below.

1 - Tag input from Tauffer consulting

Figure 1 - Tag input

enter image description here

The snippet below is a complete example for JupyterDash. For a complete Dash example you should take a look at the main source

import dash_cool_components
import dash
from dash.dependencies import Input, Output
import dash_html_components as html
import dash_bootstrap_components as dbc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from jupyter_dash import JupyterDash
import dash_core_components as dcc

app = JupyterDash()
app.layout = dbc.Container([
    dbc.Row([
        dbc.Col(
            width={'size':4}
        ),
        dbc.Col(
            dash_cool_components.TagInput(
                id="input",
            ), width={'size':4}
        ),
        dbc.Col([
            dbc.Label('Current tags'),
            dbc.Input(
                id="output",
            ),
        ], width={'size':4})
    ]),
    html.Div(id='hidden')
], style={'marginTop': '200px'})

@app.callback(
    Output('output', 'value'),
    [Input('input', 'value')]
)
def timezone_test(value):
    if value:
        tags = [e['displayValue'] for e in value]
        return tags


app.run_server(mode='inline', port = 9889)

2 - Built-in dash components

This suggestion is based on elements from Allow User to Create New Options in dcc.Dropdown on the Plotly community forum and will produce the following setup with an Input field, a submit button and a dropdown menu where multiple selections are allowed:

enter image description here

['a', 'b', 'c'] are specified as existing options (although you have speciefied that you have none) and 'a' is set up as a pre-defined choice. From here you can simply add an option d in the input field, and it will become available in the dropdown menu upon clicking Add Option. If you'd like to remove any of the options, just click the x next to it.

enter image description here

The following code snippet is written for JupyterDash, but can easily be converted to Dash. If anything is unclear, just let me know.

Complete code:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
from jupyter_dash import JupyterDash
import dash_core_components as dcc

# app = dash.Dash(__name__)
app = JupyterDash()

app.layout = html.Div([
    dcc.Input(id='input', value=''),
    html.Button('Add Option', id='submit'),
    dcc.Dropdown(
        id='dropdown',
        options=[
            {'label': 'a', 'value': 'a'},
            {'label': 'b', 'value': 'b'},
            {'label': 'c', 'value': 'c'},
        ],
        value='a',
        multi = True
    ),
])

@app.callback(
    Output('dropdown', 'options'),
    [Input('submit', 'n_clicks')],
    [State('input', 'value'),
     State('dropdown', 'options')],
)
def callback(n_clicks, new_value, current_options):
    print(n_clicks)
    if not n_clicks:
        return current_options

    current_options.append({'label': new_value, 'value': new_value})
    return current_options

app.run_server(mode='inline', port = 9889)
vestland
  • 55,229
  • 37
  • 187
  • 305
  • Thank you, it's close to what I need. I probably made myself unclear, but what I'm looking for is tag input suggested by @Barmar. I'll test a solution based on tag input implemented in https://github.com/Tauffer-Consulting/dash-cool-components – Wojciech Książek Oct 23 '21 at 09:10
  • I know. That looks great, but I would like to show you how you could do ot with components that were already built in. I'm looking forward to seeing other suggestions though. If you don't get that resource working, I'll take a look myself when I find the time. – vestland Oct 23 '21 at 10:17