Multiple pages and html forms

I’m trying to create a multi page app that uses a form. Basically, I’d like to let a user configure some options and then when they click submit take them to another page.

I’m using flask-session to store session data.

Heres what I have so far:

app.py:

import dash

app = dash.Dash()

server = app.server
server.config['SESSION_TYPE'] = 'filesystem'
server.config['SECRET_KEY'] = 'mysecretkey'
app.config.suppress_callback_exceptions = True

user_config.py:

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

from app import app


layout = html.Div([
    html.Form(id='form', children=[
        dcc.Input(id='title',
                  placeholder='Title',
                  type='text',
                  value=''),
        dcc.Input(id='pth',
                  placeholder='Path to data',
                  type='text',
                  value=''),
        html.Button('Submit', id='submit_button')]),
    dcc.Location(id='url', refresh=False)
])

@app.callback(output=Output('url', 'pathname'),
              state=[State('title', 'value'),
                     State('pth', 'value')],
              events=[Event('submit_button', 'click')])
def submit(title, pth):
    session['configured'] = True
    session['title'] = title
    session['pth'] = pth
    return '/homepage'

homepage.py:

import dash_html_components as html
from flask import session

from app import app

layout = html.Div([html.H3('TODO')])

viz.py:

#!/usr/bin/env python
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
from flask import session
from flask_session import Session

from app import app
from pages import homepage, user_config

app.layout = html.Div([
    dcc.Location(id='url', refresh=False),
    html.Div(id='page-content')
])


@app.callback(Output('page-content', 'children'),
              [Input('url', 'pathname')])
def display_page(pathname):
    if pathname == '/':
        return user_config.layout
    elif pathname == '/homepage':
        return homepage.layout


if __name__ == '__main__':

    sess = Session()
    sess.init_app(app.server)
    app.run_server(debug=True)

My problem is that I’m just constantly getting POST requests when I load the user config page ie:

 * Serving Flask app "viz" (lazy loading)                                                                 
 * Environment: production                                                                                
   WARNING: Do not use the development server in a production environment.                                
   Use a production WSGI server instead.                                                                  
 * Debug mode: off                                                                                        
 * Running on http://127.0.0.1:8050/ (Press CTRL+C to quit)                                               
127.0.0.1 - - [21/May/2018 10:41:48] "GET / HTTP/1.1" 200 -                                               
127.0.0.1 - - [21/May/2018 10:41:48] "GET /_dash-layout HTTP/1.1" 200 -                                   
127.0.0.1 - - [21/May/2018 10:41:48] "GET /_dash-dependencies HTTP/1.1" 200 -                             
127.0.0.1 - - [21/May/2018 10:41:48] "POST /_dash-update-component HTTP/1.1" 200 -                        
127.0.0.1 - - [21/May/2018 10:41:48] "POST /_dash-update-component HTTP/1.1" 200 -                        
127.0.0.1 - - [21/May/2018 10:41:48] "POST /_dash-update-component HTTP/1.1" 200 -                        
127.0.0.1 - - [21/May/2018 10:41:48] "POST /_dash-update-component HTTP/1.1" 200 -                        
127.0.0.1 - - [21/May/2018 10:41:48] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/May/2018 10:41:48] "POST /_dash-update-component HTTP/1.1" 200 -                        
127.0.0.1 - - [21/May/2018 10:41:49] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/May/2018 10:41:49] "POST /_dash-update-component HTTP/1.1" 200 -                        
127.0.0.1 - - [21/May/2018 10:41:49] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/May/2018 10:41:49] "POST /_dash-update-component HTTP/1.1" 200 -                        
127.0.0.1 - - [21/May/2018 10:41:49] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [21/May/2018 10:41:49] "POST /_dash-update-component HTTP/1.1" 200 -                        
127.0.0.1 - - [21/May/2018 10:41:49] "POST /_dash-update-component HTTP/1.1" 200 - 
127.0.0.1 - - [21/May/2018 10:41:49] "POST /_dash-update-component HTTP/1.1" 200 -       
...

I think my issue might be related to this: https://github.com/plotly/dash-core-components/issues/44 but I’m not sure.

Thanks for writing in. You’re right that isn’t the way URL routing is meant to work at the moment, and you indeed have the infinite loop Chris mentioned in the referenced issue.

Something like this should be possible without using URL as an output. Wherever you have a callback changing the URL, you could simply use links that lead to new URLs.