Is it possible to generate callbacks with random Inputs?

Hi there,

my question is: is it possible to generate callback with not predefined number of inputs?

For example, I parse file by clicking button, generate list of id’s for Inputs, and then want to generate as much Inputs in callback, as id’s in list.

example:

inputslist=[]
idforinputs=['id1','id2','id3','id4','id5']
for elements in idforinputs:
 inputslist.append(dcc.Input(id=elements))
 

app.callback(Output(**something**),inputlist)

Also, the other question is:
is there a way to connect different inputs to one output? I tried to make a workaround for the first question and decided to make callback for every element I create. However, because of the fact that reaction is the same (for example, customer clicked generated link and data should be transfered to another app in it’s Div) I get error:
dash.exceptions.DuplicateCallbackOutput:

We’re actively building a solution for this right now. See https://github.com/plotly/dash/issues/475 for discussion.

Before that’s out, the only solution I’m aware of is to pre-create as many elements as you’re ever going to support, and leave any unused ones hidden.

Re: your second question: no, a given output needs to be specified by only one callback. Otherwise it would be ambiguous.

Hi Alex, thanks for the answer!

So, does it meant that I should create, lets say, 30 insivible elements, like html.Div, for example, and track down their children property in callback?

to make it clear:
Lets say I created 30 html.Div’s (all invisible).
In first callback I generate, lets say, 30 html.A objects
I write every object ,every html.A, to every Div I created above.
Then I create second one, big callback,where Inputs are ‘children’ properties of those 30 Div’s, and Output is one - my second app’s main Div
Now I only need to know, which link from the generated links was clicked by user. Since every of 30 Div’s will hold something like that:
html.A('link1_name', href='/apps/app2', id='link1_id')
I still cant imagine how to understand that exactly this element was clicked.
Would appreciate any advice

oh if you can do it through the app’s URL I think there’s a much easier way - use dcc.Link and dcc.Location - see https://dash.plot.ly/urls and notice the callback that responds to the location need not serve the entire page, it can be just a part.

Now if you do it that way your last question may not be relevant right now, but since you asked:

I still cant imagine how to understand that exactly this element was clicked.

yeah we need to document this better… see dash.callback_context.triggered, described in https://dash.plot.ly/faqsQ: How do I determine which Input has changed?

But in callback as input we use ‘children’ property of Div, not html.A
And if I will use dash.callback_context.triggered , then I will receive id of the Div, while I need id of the html.A

I was suggesting replacing the html.A elements with dcc.Link - what happens then is all of these write to the page URL, and you can then read this back in via dcc.Location - its pathname prop effectively tells you which element was clicked.

But if you really want to do it with html.A, the route I’d take is: pre-create 30 html.A elements, but hide the unused ones. Then your second callback takes the n_clicks prop of all 30 html.A elements as inputs; dash.callback_context.triggered will tell you which one was clicked.

Got it, thanks! Will try it now

I finally made it and decided to use transfer info via dcc.Link (so all links are unique and I’m analysing “path” property to parse it further).
However, I faced new problem:
1) dcc.Link have no property to open link in new tab (while html.A have property “target”), and ofcourse it is possible to open link in new tab with right click or with scroll click, but ‘typical’ user use left click for this.Is it possible to change behaviour of dcc.Link to be opened in new tab by default?

Oh if you want a new tab, you can just use html.A - but keep dcc.Location for setting the page contents. The key reason to use dcc.Link is to avoid reloading the page, so the transition can be much faster. But in a new tab there’s no avoiding recreating the environment so nothing is lost with html.A.

Got it, thank you very much!
I didn’t realize that this is a common approach- transfer data via url. The problem of my experience, ofcourse.