Dash-renderer will not render wildcard attributes
rmarren1 opened this issue · 3 comments
I added in plotly/dash-html-components#40 a wildcard attribute to handle the HTML data-* attributes.
This works fine for adding a data-* attribute to an object, and within callbacks you can update this value and use it to correctly to update other callbacks.
However, this attribute is not injected into the HTML on the client side, and it cannot be used to interact with javascript and css on the client side?
Any idea where to start for fixing this issue? I am guessing that there is a subset of properties that are actually rendered in HTML on the client side, and I could add wildcard attributes there. I am having trouble finding the piece of code that does this.
Hm, at first glance I'm actually not quite sure. dash-renderer
shouldn't interfere with which properties can be rendered, that should be up to the component. And inside, the component, we're just passing all of the props through:
https://github.com/plotly/dash-html-components/blob/0d65ea60acdd9ee988e89a7b0e70d125edf53c89/src/components/Div.react.js#L20
I'll pull down the branches and take a look
Looking at the React tree (I use the react devtools: https://github.com/facebook/react-devtools), it looks like the data-*
props aren't supplied to the tree.
Looking into the network request (/_dash-layout
serves the app.layout
to the front-end), it looks like the data-* prop wasn't serialized:
So, I suspect the issue has to do with serializing the component. Indeed, using the JSON serializer:
In [3]: import dash_html_components as html
...: import json
...: from plotly.utils import PlotlyJSONEncoder
...:
...: c = html.Div(
...: id="my-id",
...: children='data-*',
...: **{
...: 'data-foo': 'foo',
...: 'data-bar': 'bar'
...: }
...: )
...:
...: print(json.dumps(c, cls=PlotlyJSONEncoder, indent=2))
...:
{
"type": "Div",
"namespace": "dash_html_components",
"props": {
"children": "data-*",
"id": "my-id"
}
}
This serialization happens here: https://github.com/plotly/dash/blob/ff93d2c4331a576b445be87bb3b77576f18b030a/dash/dash.py#L159-L167
The cls=PlotlyJSONEncoder
is here: https://github.com/plotly/plotly.py/blob/master/plotly/utils.py#L105, but the main thing to know is that the encoder looks for a .to_plotly_json
method. This is supplied in Dash here: https://github.com/plotly/dash/blob/ff93d2c4331a576b445be87bb3b77576f18b030a/dash/development/base_component.py#L36-L45. It's likely that this needs to be updated
def to_plotly_json(self):
# Add normal properties
props = {
p: getattr(self, p)
for p in self._prop_names # pylint: disable=no-member
if hasattr(self, p)
}
# Add the wildcard properties data-* and aria-*
props.update({
k: getattr(self, k)
for k in self.__dict__
if any(k.startswith(w) for w in
self._valid_wildcard_attributes) # pylint:disable=no-member
})
as_json = {
'props': props,
'type': self._type, # pylint: disable=no-member
'namespace': self._namespace # pylint: disable=no-member
}
return as_json
to fix.