The dccType is basically a component factory that allows for a simpler and less error-prone syntax for generating callbacks and referencing components in an object-oriented manner
import dash
from dash.dependencies import Input, Output, State, Event
import dash_core_components as dcc
import dash_html_components as html
class dccType(object):
def __init__(self, divtype, component_property = 'value', string = str, **kwargs):
self.divtype = divtype
self.kwargs = kwargs
self.component_property = component_property
self.string = string
def div(self, *args, **kwargs):
div_dict = {}
for k,v in self.kwargs.items():
try:
div_dict[k] = v(*args)
except:
div_dict[k] = v
for k,v in kwargs.items():
div_dict[k] = v
return self.divtype(**div_dict)
def input(self, *args, **kwargs):
component_property = kwargs.pop('component_property', self.component_property)
try:
return Input(self.id(*args), component_property)
except:
return Input(self.kwargs['id'], component_property)
def output(self, *args, **kwargs):
component_property = kwargs.pop('component_property', self.component_property)
try:
return Output(self.id(*args), component_property)
except:
return Output(self.kwargs['id'], component_property)
def state(self, *args, **kwargs):
component_property = kwargs.pop('component_property', self.component_property)
try:
return State(self.id(*args), component_property)
except:
return State(self.kwargs['id'], component_property)
def event(self, *args, **kwargs):
component_property = kwargs.pop('component_property', self.component_property)
try:
return Event(self.id(*args), component_property)
except:
return Event(self.kwargs['id'], component_property)
def id(self, *args):
return self.kwargs['id'](*args)
app = dash.Dash()
app.css.append_css({'external_url': 'https://codepen.io/chriddyp/pen/bWLwgP.css'})
app.config['suppress_callback_exceptions']=False
greeting = dccType(
html.Div,
id = 'an-id-you-never-need-to-type-again',
children = ['Hello World'],
component_property = 'children')
greeting_options = dccType(
dcc.Dropdown,
id = 'dropdown-id-blah-blah',
options=[
{'label': 'Hi there!', 'value': 'Hi there!'},
{'label': 'Hello Cleveland!', 'value': 'Hello Cleveland!'},
{'label': 'Hi San Francisco!', 'value': 'Hi San Francisco!'}
],
value='Hi there!', #the default component_property is 'value'
)
### Lambdas for component properties allows for more component reuse
greeting_style = dccType(
dcc.Dropdown,
id = lambda prefix: '{}-style'.format(prefix),
options = [
dict(label = 'white', value = 'white'),
dict(label = 'red', value = 'red'),
dict(label = 'blue', value = 'blue')
],
value = 'white')
options_outer = dccType(
html.Div,
children = [greeting_options.div(),
greeting_style.div('background'),
greeting_style.div('text')],
className = 'two columns')
app.layout = html.Div(children=[greeting.div(), options_outer.div()])
@app.callback(greeting.output(), [greeting_options.input()])
def update_greeting(dropdown_value):
return dropdown_value
@app.callback(
greeting.output(component_property = 'style'),
[greeting_style.input('background'), greeting_style.input('text')])
def update_greeting_style(bgcolor, textcolor):
return dict(background = bgcolor, color = textcolor)
if __name__ == '__main__':
app.run_server(debug=True, port = 8000)