Show and Tell - Dash Bootstrap Components

Amazing - thank you! :grinning:

1 Like

@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?

1 Like

Glad you’ve enjoyed using it :slight_smile:

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.

2 Likes

@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.

6 Likes

@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!

1 Like

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'
2 Likes

@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

1 Like

@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 :slightly_smiling_face:

2 Likes

@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.

1 Like

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.

2 Likes

thanks a lot it was my mistake i was messing with the wrong class

1 Like

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.

image

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.

2 Likes