Adding entries to Dropdowns

Hey,

I am creating a dashboard that is essentially a form where the user enters data which will then get saved to a database upon submitting. In the form I have multiple dropdowns that will allow the user to select options from. If an option is not in the dropdown, I would like to give the user a chance to manually type in an entry and hit enter. I have multi-selct dropdowns as well as dropdowns in Dash datatables and I would like each dropdown to have this functionality. How might I implement this?

Thanks!

Hi @Kmike,

you could add a dcc.Input() and a Button for each dropdown and update the drop-down options on click of the button.

You could create two Input() and one Button where the first Input() indicates the drop-down to change and the second Input() is the actual option you would like to add.

Hi,
Thanks for the idea. However that seems a bit excessive for the number of drop downs I have on the page. Plus the drop
-downs I have in the DataTables.

I think I’m going to make each drop-down contain an ‘Add new’ selection. If that selection is selected then I will create a pop up with an input box and an add button that allows the user to update the drop-down list. I haven’t tried this yet but when I do will try to post my results.

1 Like

This sounds nice!

Please post your result here (or if you need assistance during the process)

I’m having trouble getting my callback to work. I narrowed it down to the if statement in my show_modal function. For some reason this if statement is never true thus does not trigger the modal to pop up. Anyone have a reason why?

Blockquote
@app.callback(
Output(‘dd-entry-modal’,‘is_open’),
Input(‘tc_dd’, ‘value’)
)
def show_modal(value):
if value==‘Add New’:
return True

So I resolved my callback issue above by changing value to a list. However now I want to check the list to see if value contains the string ‘Add New’. I’ve been trying to iterate the list by checking if ‘Add new’ in value ==True but this is not working. I get no errors but the function never gets set to true. Here is my code:

Blockquote
dcc.Dropdown([‘Dude1’, ‘AOB’,‘Add New’],id=‘tc_dd’, multi=True, value=),
html.H6(id=‘test’),

Blockquote
@app.callback(
Output(‘dd-entry-modal’,‘is_open’),
Input(‘tc_dd’, ‘value’),
)
def show_modal(value):
if ‘Add New’ in value ==True:
return True

HI @Kmike,

Unfortunately I can’t help you because the code you provide does not contain enough information. Since I liked your idea of adding drop down options by selecting a certain, already existing option, I came up with a possible solution:

1 Like

Thank you for this! However I have multi-selectable dropdowns as well. How should I implement this with the multi-selectable dropdowns. I have attempted to do this with my code, but for some reason I cannot get this to work.

from dash import Dash, html, dcc, dash_table
from dash.dependencies import Input, Output, State
import dash_bootstrap_components as dbc

app = Dash(__name__)
app.layout = dbc.Container([
    dbc.Row(
        dbc.Col(
            (html.H6('People'),
             dcc.Dropdown(['Person 1', 'Person 2','Add New'],id='dd', multi=True, value=[ ]),
             html.H6(id='test'), #Used as a test output to print dropdown selection and its class
             dbc.Modal(
                     [
                         dbc.ModalHeader(children='Add New', id='modal-head'),
                         dbc.ModalBody(
                             [
                                 dbc.Label(id='modal-label'),
                                 dbc.Input(id="modal-input", type="text"),
                             ]
                         ),
                         dbc.ModalFooter(
                             [
                                 dbc.Button("Add", color="primary", id="modal-add"),
                                 dbc.Button("Cancel", id="modal-cancel"),
                             ]
                         ),
                     ],
                     id="dd-entry-modal", is_open=False
                 ),
            )
        )
    )
])
@app.callback(
    Output('dd-entry-modal','is_open'),
    Input('dd', 'value'),
)
def show_modal(value):
    if 'Add New' in value ==True:
        return True

#Callback to print dropdown input values and class
@app.callback(
    Output('test','children'),
    Input('dd', 'value'),
)

def test(value):
    return str(value)+' '+str(type(value))

if __name__ == '__main__':
    app.run_server(debug=True)

HI @Kmike,

a few points:

  • Since you want to use the dbc.Modal() you have to include a dbc.theme as external_stylesheet when initiating the app.

  • The reason for your modal not to show up is the line if 'Add New' in value ==True. You have to delte the ==True as the expression if 'Add New' in value returns True or False.

  • There are variuos actions which could trigger the visibility of the modal:

    • selecting values from the drop-down
    • click on ‘Add’
    • click on ‘Cancel’

In Dash you have to combine these three actions into one callback as they change the same property of a single component (is_open)

Hi @Kmike ,

This is the version for multi=True

1 Like

Thank you @AIMPED! You’ve been so helpful!

1 Like

@AIMPED
I have one more question about this. Is there a way to implement this in a DataTable. I have multiple DataTables with dropdown entries as well. I have created a function to create the tables, but now I am trying to tie it to the callback. Here is the function that creates my DataTable.

#Draws a table with a Title, df=data, dd=list of dropdown columns
def drawTable(Title,df,dd):
    col=[] #initialize column list
    opt={} #initialize drop down options
    #Create columns and the associated dropdown options
    for i in df.columns:
        if i in dd: #dd stands for dropdown so if column is in the dropdown list execute this statement
            #ddc stands for dropdown column
            ddc={"name": [Title,i], "id": i, 'presentation':'dropdown'}
            col.append(ddc)
            #Create Dropdown options (ddo)
            ddo={i:{'options':[{'label':'Add New','value':'Add New'}]+[{'label':o, 'value':o} for o in df[i].unique()]}} 
            opt.update(ddo)       
        else:
            c={"name": [Title,i], "id": i}
            col.append(c)
    return html.Div([
        dash_table.DataTable(
        id={'type': 'tbl', 'index': Title},
        data=df.to_dict('records'),
        columns=col,
        editable=True,
        row_deletable=True,
        dropdown=opt,
        style_data={'color': 'black','backgroundColor': '#CDE5E8'},
        style_data_conditional=[{'if': {'row_index': 'odd'},'backgroundColor': 'rgb(232, 242, 244)'}],
        style_header={'backgroundColor': 'rgb(46, 179, 190)','color': 'white','fontWeight': 'bold','textAlign': 'center'},
        merge_duplicate_headers=True,
        ),
    dbc.Button('Add Row', id={'type': 'btn', 'index': Title}, n_clicks=0,style= {'backgroundColor': 'rgb(46, 179, 190'}, class_name='mt-0 mb-1')
])