A.G
A.G

Reputation: 17

Dynamically render tabs with python dash

Does someone know how I would dynamically render tabs based on a given input?

For example, if I put a number(like 4) in a text box and pressed submit, I'd want to have 4 tabs show up underneath with content(let's the tab number underneath). If put 2 I'd want 2 tabs. I think I use a for loop somewhere but not sure how to implement.

I've only been able to get to show a static number of tabs once submit is clicked to start off.

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


app = dash.Dash()

input_group_Row = dbc.Row([ dbc.Col([        
    dbc.CardBody(
        [
            dbc.InputGroup(
            [
                dbc.InputGroupAddon("Enter number", addon_type="prepend"),
                dbc.Input(id='integer',placeholder="Enter int"),
            ],className="mb-3",),
            ]),
    
                                ]),     
    dbc.Col([
        dbc.Button('Enter', color='primary',id='load', block=True,n_clicks=0),
            ]) 
        ])
app.layout = html.Div([input_group_Row, html.Div(id='output-content')], style = CONTENT_STYLE)

@app.callback(Output('output-content', 'children'),
              [Input('load', 'n_clicks')],
              [State('integer','value')],
              )
def render_tabs(click1, integ):
    output =""
    ctx = dash.callback_context
    action = ctx.triggered[0]['prop_id'].split('.')[0]
    if action == 'load':
        print(type(int(integ)))
        output = integ
        return dcc.Tabs(id='tab', value='tab1',children=[
            dcc.Tab(label='Tab 1', value='tab1', children=[html.Div(output,style={'color': 'blue', 'fontSize': 140})]),
            dcc.Tab(label='Tab 2', value='tab2', children=[html.Div(int(output)+3,style={'color': 'blue', 'fontSize': 140})])
        ])


Upvotes: 0

Views: 2594

Answers (1)

bas
bas

Reputation: 15722

You could use a list comprehension.

List comprehensions provide a concise way to create lists. Common applications are to make new lists where each element is the result of some operations applied to each member of another sequence or iterable, or to create a subsequence of those elements that satisfy a certain condition.

https://docs.python.org/3/tutorial/datastructures.html


Based on your example you could do something like this:

@app.callback(
    Output("output-content", "children"),
    [Input("load", "n_clicks")],
    [State("integer", "value")],
)
def render_tabs(click1, integ):
    output = ""
    ctx = dash.callback_context
    action = ctx.triggered[0]["prop_id"].split(".")[0]
    if action == "load":
        output = int(integ)
        return dcc.Tabs(
            id="tab",
            value="tab1",
            children=[
                dcc.Tab(
                    label=f"Tab {num + 1}",
                    value=f"tab{num + 1}",
                    children=[html.Div(num)],
                )
                for num in range(output)
            ],
        )

The same solution with a for loop could look like this:

@app.callback(
    Output("output-content", "children"),
    [Input("load", "n_clicks")],
    [State("integer", "value")],
)
def render_tabs(click1, integ):
    output = ""
    ctx = dash.callback_context
    action = ctx.triggered[0]["prop_id"].split(".")[0]

    if action == "load":
        output = int(integ)

        tabs = []
        for num in range(output):
            tabs.append(
                dcc.Tab(
                    label=f"Tab {num + 1}",
                    value=f"tab{num + 1}",
                    children=[html.Div(num)],
                )
            )

        return dcc.Tabs(
            id="tab",
            value="tab1",
            children=tabs,
        )

Upvotes: 2

Related Questions