Dynamic Number of Outputs

Hello All,

I am attempting to build a duel-layer input section. The first layer is the number of “Jobs” to create. The second layer is the number of “Hazards” related to each specified “Job”. Effectively the goal is to allow a user to generate rows of a dataframe which will be sent to a SQL server.

However I am struggling how to incorporate unique sets of “hazard” areas per “job”. Below is a desired output (where the number of jobs and subset hazards could be infinite) and my attempted code.

Any Ideas? Is this even possible in Dash?

Code:

@app.callback(Output('job', 'children'),
              [Input('job-button', 'n_clicks')])
def jobs(clicks):
    return html.Div(
        [
            html.Div(
                [
                    html.P('Job:'),
                    dcc.Input(id = 'job-{}'.format(i)),
                    html.P('Job Step:'),
                    dcc.Input(id = 'job-step-{}'.format(i)),
                    html.Div(id = 'hazard-{}'.format(i)),
                    html.Div(
                        [
                            html.Button('Add Hazard', 
                                id = 'hazard-button-{}'.format(i), 
                                n_clicks = 1, 
                                style = {'justify-self': 'end'},
                            ),
                        ],
                        style = {'justify-self': 'end'},
                        className = 'row'
                    ),
                ]
            ) for i in range(1, clicks + 1)
        ]
    )

@app.callback([Output('hazard-{}'.format(i), 'children') for i in range(1, Input('job-button', 'n_clicks'))],
              [(Input('hazard-button-{}'.format(i), 'n_clicks'), i) for i in range(1, Input('job-button', 'n_clicks'))]
             )
def hazard(clicks):
    return html.Div(
        [
            html.Div(
                [
                    html.Div(
                        [
                            html.Hr(),
                            html.P('Hazard'),
                            html.Input(id = 'hazard-{}-{}'.format(click[1], i)),
                            html.P('Probability:'),
                            html.Input(id = 'init-prob-{}-{}'.format(click[1], i)),
                            html.P('Consequence:'),
                            html.Input(id = 'init-con-{}-{}'.format(click[1], i)),
                        ]
                    ) for i in range(1, click[0] + 1)
                ]
            ) for click in clicks 
        ]
    )

See Dynamic Controls and Dynamic Output Components

So in other words, its not possible?

Not really, at least dynamically. I use a method where I create some large number of things at the beginning; when i need to show another, I just change style from dict(display=hidden) to dict().