Amazing - thank you!
@tcbegley I just wanted to say thanks, I finally got around to really trying to implement this on my apps last week and after a day of getting to understand Bootstrap a little bit it’s made the job of laying out my sites much simpler and more flexible.
One thing I was trying and failing to do, which I now suspect was just the wrong approach, was getting animations to work with real layout changes.
E.g. with 2 columns I wanted 1 to disappear, I tried using collapse and setting the width to zero but it made the the 2nd column fall below the 1st column and then the collapse occurred causing the 2nd column to then jump up. I assume this was just not how this was conceived to be used?
Glad you’ve enjoyed using it
Could you describe a bit more the effect you’re going for? Also any kind of code snippet that shows what you tried in a little bit more detail. You’re right that the collapse is not really designed for this, but there might be a way to achieve the effect you want with a little bit of hacking.
Col
doesn’t do any input validation (perhaps it should), so if you set width=0
the Col
will try to apply a class called col-0
which doesn’t exist, and it will call back on the default behaviour specified in the col
class which is probably why you saw the column expand and wrap onto a new line.
So this has been really useful, but I was wondering how I would go about partitioning and customizing the ‘brand’ attribute?
Let’s say I wanted my ‘brand’ in my SimpleNav be ‘ABC’ where each letter was a different color, how would I go about doing that?
Thanks,
Hey @sclavijo,
To achieve that sort of thing you will probably need to use Navbar
instead of NavbarSimple
, then wrap each character in a html.Span
and set the colour. Here’s a simple example
import dash
import dash_bootstrap_components as dbc
import dash_html_components as html
app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = dbc.Navbar(
dbc.Container(
[
dbc.NavbarBrand(
[
html.Span("A", style={"color": "red"}),
html.Span("B", style={"color": "green"}),
html.Span("C", style={"color": "blue"}),
]
),
dbc.Nav(
[
dbc.NavItem(dbc.NavLink("Item 1", href="#")),
dbc.NavItem(dbc.NavLink("Item 2", href="#")),
],
navbar=True,
),
]
)
)
if __name__ == "__main__":
app.run_server(debug=True)
There’s a bunch more Navbar
examples here.
The reason you’ll struggle to do the same with NavbarSimple
is that (currently at least), you can only pass dash components to the children
prop of other dash components, so you wouldn’t be able to use html.Span
like above with the brand
prop. The only alternative would be if it’s possible to write CSS to cycle through colours each character, but that sounds pretty nasty to me and might not be possible anyway.
Hope that helps.
@sriotti and anyone else interested: I finally added some simple multi-page examples to our repo like I’ve been promising for a long time. Check them out here. They include a navbar example, plus multiple sidebar examples, including collapsible submenus and responsive designs. Try running them or check out some screenshots on the pull request.
Also more generally, the release of Dash 0.41.0 let us add some cool new features. Personally I’m pretty excited about the new Modal component, which lets you easily add modals to your apps without having to fiddle around with CSS and z-indexes. Check out the steadily improving documentation or our repo to see the new stuff we’re adding.
@tcbegley Great work Tom. Really appreciate the time and effort you have put into dbc. I look forward to using these new components and am excited to see what’s next!
Hello,
I have extensively read over the multi-app program, and I finally understand it. I tested other apps and it works. I am however stuff at how to create a callback for connecting the different DropdownMenuItem instances I have to pull out a new page (i.e. i am confused with how to make inputs and outputs of the callback). I only need help with the index page. Here is my structure:
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
import socket
from app import app
import page_1, page_2, page_3
import base64
image_filename = 'file/path.png'
encoded_image = base64.b64encode(open(image_filename, 'rb').read())
app.layout = html.Div([
html.Img(
id = 'image',
alt='Image',
src='data:image/png;base64,{}'.format(encoded_image.decode()),
style= {
'width':'100%',
'height':'100px'
}
),
dbc.NavbarSimple([
dbc.DropdownMenu(
id = 'Menu',
nav=True,
in_navbar=True,
label="Menu",
children=[
dbc.DropdownMenuItem("Page 1",href='/page_1'),
dbc.DropdownMenuItem("Page 2",href='/page_2'),
dbc.DropdownMenuItem("Page 3",href='/page_3')
]
)
]),
html.Div(id='page-content')
])
@app.callback(Output('page-content', 'children'),
[Input('Menu', 'href')])
def display_page(pathname):
if pathname in ('/page_1','',None,'/'):
return page_1.layout
elif pathname == '/page_2':
return page_2.layout
elif pathname == '/page_3':
return page_3.layout
else:
return '404'
host = socket.gethostbyname(socket.gethostname())
app.run_server(debug=False, host=host, port = 1002)
Hey @dayxx369
You need to add the dcc.Location
component to your layout, then use it in a callback to monitor the pathname and render the layout accordingly. When you set href
on each of the DropdownMenuItem
components, they behave just like dcc.Link
, so you don’t need to use either the DropdownMenu
or DropdownMenuItem
as inputs to any callbacks.
Something like this:
# add dcc.Location to your layout
app.layout = html.Div([
dcc.Location(id="url"),
...
])
# use Location in the display_page callback
@app.callback(Output('page-content', 'children'),
[Input('url', 'pathname')])
def display_page(pathname):
if pathname in ('/page_1','',None,'/'):
return page_1.layout
elif pathname == '/page_2':
return page_2.layout
elif pathname == '/page_3':
return page_3.layout
else:
return '404'
@tcbegley
Great. I understand. Now, should I have the NavbarSimple in the index or should it be redefined in the other programs? I want to set the dropdown item to disabled if it’s currently on that page (i.e. other apps). Thanks again
really nice work can’t wait to test it
@tcbegley
Nevermind, I answered my own question. The NavbarSimple should be redefined in the other programs (apps). I am really looking forward to how dash evolves!
@dayxx369
Correct, put the NavbarSimple
in the index. The top level structure of the app should be something like
app.layout = html.Div([
dcc.Location(...),
dbc.NavbarSimple(...),
html.Div(id="page-content"),
])
EDIT - You got in just before me, but I’ll leave my answer in case it helps someone else
@dayxx369, sorry for the spam…
On the question of disabling links in the navbar depending on which page you’re on, you can write a callback that takes the location as an input, and sets the disabled
prop of the relevant DropdownMenuItem
accordingly. Though I would have thought that setting the active
prop rather than disabled
might be more natural?
Check out this example which does something similar with NavLink
rather than DropdownMenuItem
. I think you should be able to adapt it to your case pretty easily.
Oh yes, I figured that out as well. thanks again!
Question. Can i still override css classes with my custom CSS file in the assets folder if i use your components??
Yes absolutely! All of the styles are applied through CSS anyway, so you can modify or add to them as you please.
dbc.themes.BOOTSTRAP
is just a link to BootstrapCDN, if you prefer you can have a local copy of Bootstrap CSS, or a modified copy of it, or you can complement it with your own CSS.
thanks a lot it was my mistake i was messing with the wrong class
Does anyone know how to use Sliders and Dropdown with dbc?
They seem to have been added here - https://github.com/facultyai/dash-bootstrap-components/pull/297 - but when I try to use dbc.Slider / dbc.Dropdown I get this:
Traceback (most recent call last):
File "index.py", line 334, in <module>
dbc.Slider(
AttributeError: module 'dash_bootstrap_components' has no attribute 'Slider'
My dbc version is up to date
Hey @Chris369,
dash-bootstrap-components doesn’t have it’s own versions of those components (basically because we wanted to minimise unnecessary duplication of functionality). The pull request you linked to is related to custom CSS that will restyle the Slider
or Dropdown
from dash-core-components to make it look more “bootstrapy”.
The use of this custom CSS hasn’t been documented yet, in the future we’d like to host our own Bootstrap stylesheets with some Dash specific features on a CDN and make it easy to access through dbc.themes
or similar, but I haven’t got around to it.
In the meantime however, you can check out my dash-bootstrap-css repo which has compiled versions of the styles that were added in that pull request, ready for download.
To use them, just download one of the compiled stylesheets in dist/
, put it in your app’s assets/
folder, and make sure that any component you want to apply the styles to is a child of a component with className="dash-bootstrap"
. For example I downloaded the minty stylesheet, added it to assets/
then ran this app
import dash
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
app = dash.Dash()
app.layout = dbc.Container(
children=[
dcc.Slider(min=0, max=10, step=1),
dcc.Dropdown(options=[
{"label": "Option 1", "value": 1},
{"label": "Option 2", "value": 2},
]),
],
className="dash-bootstrap p-5",
)
if __name__ == "__main__":
app.run_server(debug=True)
and with that code I see these “minty” version of the Slider
and Dropdown
.
Note that I no longer need to use external_stylesheets=[dbc.themes.MINTY]
or anything like that, these are full Bootstrap stylesheets with a few extra features that can be used as a drop-in replacement for other Bootstrap stylesheets.