Components not displaying inline

I want to have a button to upload a file, and when a file is selected, it should say ‘file uploaded’ next to the button. For that, I have the following code, where I have specified style={'display': 'inline-block'} in both the upload component and the div component:

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

app = dash.Dash()
server = app.server

app.layout = html.Div(children = [
    html.Div([
        dcc.Upload(id='upload_file', children=[html.Button('Upload File', id='file_upload_btn', n_clicks=0, style={'width': '240px', 'height':'40px'})], style={'display': 'inline-block'}),
        html.Div(id='file_upload_success', style={'display': 'inline-block'})
    ])
])

@app.callback(Output('file_upload_success', 'children'),
              Input('file_upload_btn', 'n_clicks'),
              Input('upload_file', 'contents'),
              State('upload_file', 'filename'))
def update_success_message(n_clicks, contents, filename):
    if n_clicks and contents:
        return "File '{}' uploaded".format(filename)

if __name__ == '__main__':
    app.run_server(debug=True)

But it does not display the text beside the button - it displays the text below the button, as if its ignoring the style={'display': 'inline-block'} part. Why is that, and how do I fix it?

Screenshot 2021-05-27 at 9.58.50 AM

This layout works for me:

app.layout = html.Div([
    html.Div([
        dcc.Upload(id='upload_file', children=[html.Button('Upload File', id='file_upload_btn', n_clicks=0, style={'width': '240px', 'height':'40px'})])
    ], style={'display': 'inline-block'}),
    html.Div(id='file_upload_success', style={'display': 'inline-block'})
])

The problem with your solution is that if I have another file upload button, it gets displayed beside the first one as well:

app = dash.Dash()
server = app.server

app.layout = html.Div(children = [
    html.Div([
        dcc.Upload(id='upload_file', children=[html.Button('Upload File', id='file_upload_btn', n_clicks=0, style={'width': '240px', 'height':'40px'})]
    )], style={'display': 'inline-block'}),
    html.Div(id='file_upload_success', style={'display': 'inline-block'}),

    html.Div([
        dcc.Upload(id='upload_file_2', children=[html.Button('Upload File 2', id='file_upload_btn_2', n_clicks=0, style={'width': '240px', 'height':'40px'})]
    )], style={'display': 'inline-block'}),
    html.Div(id='file_upload_success_2', style={'display': 'inline-block'}),
])

@app.callback(Output('file_upload_success', 'children'),
              Input('file_upload_btn', 'n_clicks'),
              Input('upload_file', 'contents'),
              State('upload_file', 'filename'))
def update_success_message(n_clicks, contents, filename):
    if n_clicks and contents:
        return "File '{}' uploaded".format(filename)

@app.callback(Output('file_upload_success_2', 'children'),
              Input('file_upload_btn_2', 'n_clicks'),
              Input('upload_file_2', 'contents'),
              State('upload_file_2', 'filename'))
def update_success_message(n_clicks, contents, filename):
    if n_clicks and contents:
        return "File '{}' uploaded".format(filename)

if __name__ == '__main__':
    app.run_server(debug=True)

And if I instead do the app.layout for the 2 upload buttons like in my original post, then the buttons themselves get displayed one below the other (which is the way I want them), but text gets displayed below the buttons (which I want to display beside the buttons):

app.layout = html.Div(children = [
    html.Div([
        dcc.Upload(id='upload_file', children=[html.Button('Upload File', id='file_upload_btn', n_clicks=0, style={'width': '240px', 'height':'40px'})], style={'display': 'inline-block'}),
        html.Div(id='file_upload_success', style={'display': 'inline-block'})
    ]),

    html.Div([
        dcc.Upload(id='upload_file_2', children=[html.Button('Upload File 2', id='file_upload_btn_2', n_clicks=0, style={'width': '240px', 'height':'40px'})], style={'display': 'inline-block'}),
        html.Div(id='file_upload_success_2', style={'display': 'inline-block'})
    ])
])

I need to combine the two - have the two buttons appear one below the other, but have the text appear beside the corresponding button.

Put each Upload/Button pair inside another Div that doesn’t have the inline-block style like so:

app.layout = html.Div([
    html.Div([
        html.Div([
            dcc.Upload(id='upload_file', children=[html.Button('Upload File', id='file_upload_btn', n_clicks=0, style={'width': '240px', 'height':'40px'})]
        )], style={'display': 'inline-block'}),
        html.Div(id='file_upload_success', style={'display': 'inline-block'}),
    ]),
    html.Div([
        html.Div([
            dcc.Upload(id='upload_file_2', children=[html.Button('Upload File 2', id='file_upload_btn_2', n_clicks=0, style={'width': '240px', 'height':'40px'})]
        )], style={'display': 'inline-block'}),
        html.Div(id='file_upload_success_2', style={'display': 'inline-block'}),
    ])
])

I’m no html/css expert by any means so there might be a simpler solution.

1 Like