I’m reading the posts here and everyone seems fantastic. Stackoverflow hates me lol.
So, I think I’m close to one of my micro-issues….after reading here: How to pass values between pages in dash - #7 by marlon
I’m definitely not a programmer. I don’t want to take credit as one, I always state this in my posts. I’m good with details and patterns, and I learn from snippets. I think they call this a “hacker”: trying to grasp open source snippets, and modifying boilerplates to my needs.
Anywho…
From that link, I now have this:
(im not worried about glob security right now, this is just for my own local run, not a production/business/professional)
I have this whole thing based on that boilerplate (thank the lords for @marlon and his snippet)
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
print(dcc.__version__)
app = dash.Dash(__name__)
app.config.suppress_callback_exceptions = True
import os
from os import listdir
import json
import glob
#path = os.path.join("./static/io/json/")
#fils = [ x for x in os.listdir(path) if x.endswith("json") ]
FILE_LIST = glob.glob("./static/io/json/*.json")
''' INDEX LAYOUT '''
indexpage = html.Div(
# I added this id attribute
id='indexpage',
children=[
dcc.Link('Enter CIK', href='/cikpage'),
html.Br(),
dcc.Link('Select a Concept', href='/conceptspage'),
],
# I added this style attribute
style={'display': 'block', 'line-height':'0', 'height': '0', 'overflow': 'hidden'}
)
''' CIK LAYOUT '''
cikpage_layout = html.Div(
# I added this id attribute
id='cikpage_layout',
children=[
html.H1('CIK'),
dcc.Input(id='cikpage-input', placeholder='ENTER CIK', type='text'),
html.Div(id='cikpage-content'),
html.Br(),
dcc.Link('Populate Concepts', href='/conceptspage'),
html.Br(),
dcc.Link('Go back home', href='/'),
],
# I added this style attribute
style={'display': 'block', 'line-height': '0', 'height': '0', 'overflow': 'hidden'}
)
''' CONCEPTS LAYOUT '''
gaapdata = {}
for fname in FILE_LIST:
lst = []
lst.append(fname)
conceptspage()
print(cikentry)
for cikentry in lst:
with open(cikentry, "r") as f:
result = json.loads(f.read())
concepts_list = list(result['facts']['us-gaap'].keys())
gaapdata = concepts_list
gaapdata
conceptspage_layout = html.Div(
# I added this id attribute
id='conceptspage_layout',
children=[
html.H1('CONCEPTS: Select a Concept'),
# dcc.Dropdown(id='conceptspage-dropdown',options=[{'label': gaap, 'value': i} for i in gaap],),
dcc.Dropdown(gaapdata, id='conceptspage-dropdown'),
html.Div(id='conceptspage-content'),
html.Br(),
dcc.Link('Choose another CIK', href='/cikpage'),
html.Br(),
dcc.Link('Go back home', href='/'),
],
# I added this style attribute
style={'display': 'block', 'line-height': '0', 'height': '0', 'overflow': 'hidden'}
)
''' FULL APP LAYOUT '''
app.layout = html.Div([
dcc.Location(id='url', refresh=False),
html.Div(id='page-content',
# I added this children attribute
children=[indexpage, cikpage_layout, conceptspage_layout]
)
])
''' INDEX CALLBACK '''
# Update the index
@app.callback(
[dash.dependencies.Output(page, 'style') for page in ['indexpage', 'cikpage_layout', 'conceptspage_layout']],
# I turned the output into a list of pages
[dash.dependencies.Input('url', 'pathname')])
def display_page(pathname):
return_value = [{'display': 'block', 'line-height': '0', 'height': '0', 'overflow': 'hidden'} for _ in range(3)]
if pathname == '/cikpage':
return_value[1] = {'height': 'auto', 'display': 'inline-block'}
return return_value
elif pathname == '/conceptspage':
return_value[2] = {'height': 'auto', 'display': 'inline-block'}
return return_value
else:
return_value[0] = {'height': 'auto', 'display': 'inline-block'}
return return_value
''' CIK PAGE CALLBACK '''
@app.callback(dash.dependencies.Output('cikpage-content', 'children'),
[dash.dependencies.Input('cikpage-input', 'value')])
def cikpage_input(value):
return 'You have selected "{}"'.format(value)
''' CONCEPTS PAGE CALLBACK '''
@app.callback(Output('conceptspage-content', 'children'),
[Input('cikpage-input', 'value')])
def conceptspage(value):
cikentry = "{}".format(value)
return 'You selected "{}"'.format(value)
return cikentry
if __name__ == '__main__':
app.run(debug=True)
I tried modifying it, to combine index and the CIK page. working on it below….
''' IMPORTS '''
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
print(dcc.__version__)
app = dash.Dash(__name__)
app.config.suppress_callback_exceptions = True
import os
from os import listdir
import json
import glob
''' OS FILES '''
path = os.path.join("./static/io/json/", '*.json')
filst = glob.glob(path)
filst
FILE_LIST = glob.glob("./static/io/json/*.json")
''' TRAVERSE FILES ATTEMPT 1'''
def filst():
path = os.path.join("./static/io/json/")
fils = [ x for x in os.listdir(path) if x.endswith("json") ]
for lst in fils:
lst = '\n'+'\n'.join(fils)
return lst
filst = filst()
''' TRAVERSE FILES ATTEMPT 2'''
def filst_func():
ipath = os.path.join("./static/io/json/")
ifils = [ x for x in os.listdir(ipath) if x.endswith("json") ]
for lst in ifils:
for ifil in ifils:
return ifils
filst_func = filst_func()
print(filst_func)
''' GAAP CONCEPTS: EXTRACT FROM JSON, GENERATE 'LIST' (or dict? etc.), TO POPULATE A DROPDOWN '''
def gaap():
gaapdata = {}
for fname in FILE_LIST:
## i = open(fname, "r")
lst = []
lst.append(fname)
print(lst)
for cikentry in lst:
with open(cikentry, "r") as f:
result = json.loads(f.read())
concepts_list = list(result['facts']['us-gaap'].keys())
## concepts_list='\n'.join(concepts_list)
gaapdata = concepts_list
return gaapdata
gaap = gaap()
## gaap = gaap.split('\n')
''' INDEX LAYOUT '''
indexpage = html.Div(
# I added this id attribute
id='indexpage',
children=[
html.H1('Index Page'),
dcc.Input(id='indexpage-input', placeholder='ENTER CIK', type='text'),
html.Div(id='indexpage-content'),
html.Br(),
dcc.Link('Populate Concepts', href='/conceptspage'),
],
# I added this style attribute
style={'display': 'block', 'line-height':'0', 'height': '0', 'overflow': 'hidden'}
)
''' CONCEPTS LAYOUT '''
conceptspage_layout = html.Div(
# I added this id attribute
id='conceptspage_layout',
children=[
html.H1('CONCEPTS: Select a Concept'),
# dcc.Dropdown(id='conceptspage-dropdown',options=[{'label': gaap, 'value': i} for i in gaap],),
dcc.Dropdown(gaapdata(), id='conceptspage-dropdown'),
html.Div(id='conceptspage-content'),
html.Br(),
dcc.Link('Go back home', href='/'),
],
# I added this style attribute
style={'display': 'block', 'line-height': '0', 'height': '0', 'overflow': 'hidden'}
)
''' FULL APP LAYOUT '''
app.layout = html.Div([
dcc.Location(id='url', refresh=False),
html.Div(id='page-content',
# I added this children attribute
children=[indexpage, conceptspage_layout]
)
])
''' CALLBACKS '''
''' INDEX '''
@app.callback(
[dash.dependencies.Output(page, 'style') for page in ['indexpage', 'conceptspage_layout']],
# I turned the output into a list of pages
[dash.dependencies.Input('url', 'pathname')])
def display_page(pathname):
return_value = [{'display': 'block', 'line-height': '0', 'height': '0', 'overflow': 'hidden'} for _ in range(2)]
if pathname == '/conceptspage':
return_value[1] = {'height': 'auto', 'display': 'inline-block'}
return return_value
else:
return_value[0] = {'height': 'auto', 'display': 'inline-block'}
return return_value
''' '''
@app.callback(dash.dependencies.Output('indexpage-content', 'children'),
[dash.dependencies.Input('indexpage-input', 'value')])
def indexpage_input(value):
return 'You have selected "{}"'.format(value)
''' CONCEPT PAGE DROPDOWN CALLBACKS '''
@app.callback(Output('conceptspage_layout', 'children'),
[Input('indexpage-input', 'value')])
def conceptspage(value):
cikentry = "{}".format(value)
cikentry
gaapdata = {}
for fname in FILE_LIST:
lst = []
lst.append(fname)
for cikentry in lst:
with open(cikentry, "r") as f:
result = json.loads(f.read())
concepts_list = list(result['facts']['us-gaap'].keys())
gaapdata = concepts_list
gaapdata
return 'You selected "{}"'.format(value)
return conceptspage()
And finally…
if __name__ == '__main__':
app.run(debug=True)
If you’ve made it this far, please don’t hate me.
I don’t know how to pass the result from the textbox of my main index page, as an object/variable (i want to call it “cikentry”) into the function at the bottom.
and then, I don’t know how to pass the result from that function below, as a variable (i want to call it popconn, or gaapdata), back to the layout of a second page, the concepts page (which will have the dropdown)
def func():
I think that’s all it is. I hope that made sense, my head is spinning.
The thing is, I can populate the dropdown! by adjusting things around….but, it only populates from one json file from the folder.
When I try to give another entry in the textbox, the dropdown just takes from the same file… In fact, I can leave the textbox blank, and the dropdown just populates from that one file it selects. I know the problem has to do with the way i’m traversing a directory and listing the files.
P.S. : i had the same problem with flask+jinja. I was able to create 2 textboxes, populate a dropdown, but I couldn’t figure out how to pass on a selected value back to the next thing (which was a graph in that case)
after this, I want to pass a selection from the dropdown, as a variable, “concept”, for the y axis on a graph with pandas.