Selected Items, or whatever these are

Hello!

I actually don’t even know what these are called. But I would like to have something like this in my dash app. Any guidance on what they are called and how to find documentation on creating it? Thanks!

image

Hello @bpolasek,

It is kind of hard to say how to execute this, without being able to see how they execute it.

dcc.Dropdown’s have the ability to get multi, which would behave similarly to how this looks.

So what I’m looking for specifically is my clients want to be able to add things to a chart and when they do, it creates a list where if they decide they don’t want that anymore, they can quickly delete it. Something like this:

image

So it’ll be associated with the dropdown, but it’s not just the dropdown. If that makes sense.

Do you think this will solve your problem? dmc.Chip

I actually was looking at that. Is there a way for them to be created as a user selects from add event with the dropdown and date? Or do they have to be preset?

Yes, that makes sense.

You can use a dcc.dropdown to add data to the dashtable and then allow the user to remove rows.

import dash
from dash import Dash, Output, Input, dash_table, dcc, html, State

app = Dash(__name__)

app.layout = html.Div([
    dcc.Dropdown(id='selection', options=[1,2,3,4,5], style={'width':'100px'}),
    dash_table.DataTable(id='selections', columns=[{'name':'selected', 'id':'selected'}], row_deletable=True,
                         style_table={'width':'100px'})
], style={'display':'flex', 'gap':'10px'})

@app.callback(
    Output('selections', 'data'),
    Output('selection', 'value'),
    Input('selection','value'),
    State('selections','data')
)
def updateSelections(v, d):
    if v:
        if d:
            d.append({'selected':v})
        else:
            d = [{'selected':v}]
        return d, ''
    return dash.no_update, dash.no_update

app.run(port=12345, debug=True)

image

Obviously, your styling of the table will change how this looks. :slight_smile:

Sweet I’ll have to try this out. Thanks so much!

1 Like

Here is it slightly altered:

image

css

#selections table {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-grow: 1;
}
#selections tbody {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    width: 150px;
    column-gap: 10px;
    row-gap: 5px;
}

#selections tbody>tr:first-of-type {
    display: none;
}

app

import dash
from dash import Dash, Output, Input, dash_table, dcc, html, State

app = Dash(__name__)

app.layout = html.Div([
    dcc.Dropdown(id='selection', options=[1,2,3,4,5], style={'width':'100px'}),
    dash_table.DataTable(id='selections', columns=[{'name':'selected', 'id':'selected'}], row_deletable=True)
], style={'display':'flex', 'gap':'10px'})

@app.callback(
    Output('selections', 'data'),
    Output('selection', 'value'),
    Input('selection','value'),
    State('selections','data')
)
def updateSelections(v, d):
    if v:
        if d:
            d.append({'selected':v})
        else:
            d = [{'selected':v}]
        return d, ''
    return dash.no_update, dash.no_update

app.run(port=12345, debug=True)

I feel like this would probably fit your needs better. :slight_smile:

3 Likes

As a side, I know (think) you’ve built the dmc library. I’m switching to your datepicker because of the clearable option. However when I allowFreeInput and then clear, it doesn’t blank out but it goes to 1/1/20. Is there a way to disable that?

Oh awesome! Thanks so much!

@bpolasek

@jinnyzor 's solution is cool, but there is an easier way. As he mentioned in his first post, you can use a dcc.Dropdown with multi=True. In the callback you can include both the date picker and the dropdown as inputs to update the figure.

2 Likes

@jinnyzor Do you mind taking a look at this further? I’ve taken your callback and integrated it into my graph. When I select an event type and date, I not only want to it to show in the table that you showed me, but it makes a line on the graph. This works. However, when I want to remove one of the selections, it removes all the lines instead of the individual line for that selection. Thoughts?

        if event_type:
            i = 0
            if event_selections:
                event_selections.append({'selected': f"{event_date} {event_type}"})
                while i < len(event_selections):
                    event_date = event_selections[i]['selected'][:10]
                    event_type = event_selections[i]['selected'][11:]
                    event_location = df['MeasureDate'].searchsorted(f'{event_date}T00:00:00')
                    if event_type == "ModelUpdate":
                        fig3.add_vline(x=event_location, line_width=3, line_color='blue')
                        i += 1
            else:
                event_selections = [{'selected': f"{event_date} {event_type}"}]
                while i < len(event_selections):
                    event_date = event_selections[i]['selected'][:10]
                    event_type = event_selections[i]['selected'][11:]
                    event_location = df['MeasureDate'].searchsorted(f'{event_date}T00:00:00')
                    if event_type == "ModelUpdate":
                        fig3.add_vline(x=event_location, line_width=3, line_color='blue')
                        i += 1
            return dcc.Graph(figure=fig3), event_selections, ''

Nevermind got a solution! Just created a different if statement saying if the event_selections exist and then making the lines from the table info. Having to use a ‘refresh’ button to change the lines as you go.

1 Like

It probably would have been easier to drive the figure off of the data from the table instead of doing it inside the same callback. :grin:

What do you mean?

Something like this:

# triggered from button push -> pushes selections to table
if event_type:
            i = 0
            if event_selections:
                event_selections.append({'selected': f"{event_date} {event_type}"})
            else:
                event_selections = [{'selected': f"{event_date} {event_type}"}]
            return event_selections, ''


@app.callback(
    Output('target', 'children'),
    Input('selections','data')
)
def addLines(event_selections):
     if event_selections:
          while i < len(event_selections):
                    event_date = event_selections[i]['selected'][:10]
                    event_type = event_selections[i]['selected'][11:]
                    event_location = df['MeasureDate'].searchsorted(f'{event_date}T00:00:00')
                    if event_type == "ModelUpdate":
                        fig3.add_vline(x=event_location, line_width=3, line_color='blue')
                        i += 1
        return dcc.Graph(figure=fig3)

Oh I gotcha. Yeah probably lol. But it’s done :woman_shrugging:

1 Like