mat-lee / bot24

0 stars 0 forks source link

plotly dash - navigation with side-bar #6

Open dwisianto opened 7 months ago

dwisianto commented 7 months ago
"""
This app creates a simple sidebar layout using inline style arguments and the dbc.Nav component.

dcc.Location is used to track the current location, and a callback uses the
current location to render the appropriate page content. The active prop of
each NavLink is set automatically according to the current pathname. To use
this feature you must install dash-bootstrap-components >= 0.11.0.

For more details on building multi-page Dash applications, check out the Dash
documentation: https://dash.plot.ly/urls
"""

import dash
import dash_bootstrap_components as dbc
from dash import Input, Output, dcc, html

app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP])

# the style arguments for the sidebar. We use position:fixed and a fixed width
SIDEBAR_STYLE = {
    "position": "fixed",
    "top": 0,
    "left": 0,
    "bottom": 0,
    "width": "16rem",
    "padding": "2rem 1rem",
    "background-color": "#f8f9fa",
}

# the styles for the main content position it to the right of the sidebar and
# add some padding.
CONTENT_STYLE = {
    "margin-left": "18rem",
    "margin-right": "2rem",
    "padding": "2rem 1rem",
}

sidebar = html.Div(
    [
        html.H2("Sidebar", className="display-4"),
        html.Hr(),
        html.P(
            "A simple sidebar layout with navigation links", className="lead"
        ),
        dbc.Nav(
            [
                dbc.NavLink("Home", href="/", active="exact"),
                dbc.NavLink("Page 1", href="/page-1", active="exact"),
                dbc.NavLink("Page 2", href="/page-2", active="exact"),
            ],
            vertical=True,
            pills=True,
        ),
    ],
    style=SIDEBAR_STYLE,
)

content = html.Div(id="page-content", style=CONTENT_STYLE)

app.layout = html.Div([dcc.Location(id="url"), sidebar, content])

@app.callback(Output("page-content", "children"), [Input("url", "pathname")])
def render_page_content(pathname):
    if pathname == "/":
        return html.P("This is the content of the home page!")
    elif pathname == "/page-1":
        return html.P("This is the content of page 1. Yay!")
    elif pathname == "/page-2":
        return html.P("Oh cool, this is page 2!")
    # If the user tries to reach a different page, return a 404 message
    return html.Div(
        [
            html.H1("404: Not found", className="text-danger"),
            html.Hr(),
            html.P(f"The pathname {pathname} was not recognised..."),
        ],
        className="p-3 bg-light rounded-3",
    )

if __name__ == "__main__":
    app.run_server(port=8888)
dwisianto commented 6 months ago

Board with NavBar

#
#
#
class BoardNavAndBar:

    uid_url, uid_page_content = 'url', 'page-content'
    uid_url0, uid_url1, uid_url2 = '/', '/page-1', '/page-2'

    @classmethod
    def layout(cls):
        return html.Div(
            [
                dcc.Location(id=cls.uid_url),
                dbc.NavbarSimple(
                    children=[
                        dbc.NavLink("Home", href=cls.uid_url0, active="exact"),
                        dbc.NavLink("Page 1", href=cls.uid_url1, active="exact"),
                        dbc.NavLink("Page 2", href=cls.uid_url2, active="exact"),
                    ],
                    brand="Navbar with active links",
                    color="primary",
                    dark=True,
                ),
                dbc.Container(id=cls.uid_page_content, className="pt-4"),
            ]
        )

    @classmethod
    def callback(cls, ap):

        @ap.callback(Output(cls.uid_page_content, "children"), [Input(cls.uid_url, "pathname")])
        def render_page_content(pathname):
            if pathname == cls.uid_url0:
                return html.P("This is the content of the home page!")
            elif pathname == cls.uid_url1:
                return html.P("This is page 1!")
            elif pathname == cls.uid_url2:
                return html.P("Oh cool, this is page 2!")

            # If the user tries to reach a different page, return a 404 message
            return cls.page_not_found__layout(path_name=pathname)

        return ap

    @classmethod
    def page_not_found__layout(cls, path_name):
        return html.Div([
                    html.H1("404: Not found", className="text-danger"),
                    html.Hr(),
                    html.P(f"The pathname {path_name} was not recognised..."),
                ],
                className="p-3 bg-light rounded-3",)

    @classmethod
    def demo(cls):

        app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP],
                        suppress_callback_exceptions=True)

        app.layout = cls.layout()
        app = cls.callback(app)

        app.run_server(port=8888)