Reputation: 397
I am writing a dash app with Divs with images in them. I want to generate a new image when a new line to a SQLite database is added. In addition, I want clicking on this new image to move it to a different Div. The problem I'm having is that although I can add Input([new image id],n_clicks) to the list of inputs, outputs and states that I passed to the callback, it is not listening to this new input. Simplified pieces of code are:
For generating the the image:
def text(sql_row,id_name):
#font_size=16
color='blue'
image = Image.new("RGB", (400, 500), color)
draw = ImageDraw.Draw(image)
row=10
for row, item in enumerate(sql_row):
draw.text((10,35, item)
return html.Img(src=image,id=id_name)
and for adding the new image to the div, moving image to next div when clicked and for attempting to add n_clicks for the new image to the callback inputs
#create the callbacks for the function
callback_children=[Output('div1','children'),Output('div2','children')]
for img in image_list:
callback_children.append(Input(img.id,'n_clicks'))
callback_children=callback_children+[Input('interval-component', 'n_intervals')]+[State(component_id='order_in',component_property='children'),State(component_id='order_up',component_property='children'),State(component_id='order_out',component_property='children')]
@app.callback(callback_children)#children contain n_clicks input for images in divs, div children states and div children outputs
def update_orders(*args):
...
#add new image to children of div1:
global callback_children
new_img=text(new_item,str(new_sql_row))
div1_children.append(new_img)#This puts the new image in div1
callback_children.insert(3,Input(new_img.id,'n_clicks'))
#move image to next div when clicked
changed_id = [p['prop_id'] for p in ctx.triggered][0]
ctx = dash.callback_context
for item,click_value in list(ctx.inputs.items()):
img_id=str(item).split('.')[0]
if img_id in changed_id.split('.')[0]:#if image was clicked
div2_children.append(img_id)#add image to div2 children
...
#code to remove image from div1 children
...
return [div1_children, div2_children]
This code successfully adds the image to the first div and moves an image from the first div to the second when clicked, but clicking on an image that was added to the first div by the callback does nothing since its n_clicks input wasn't present in callback_children when the script was launched. Is there a way to update the callback inputs to add n_clicks for the new image?
Upvotes: 0
Views: 1657
Reputation: 6616
You'll need to use pattern-matching callbacks for this. Updating a Dash callback after initialization won't change its behavior, but these callbacks can use somewhat dynamic inputs and outputs, which should do the trick.
Upvotes: 1